/**
 * Created by Loriling on 2015/5/8.
 */
"use strict";
var softphoneAPIType = [41, 42].indexOf($E.mode) > -1 ? 'wscti' : 'localproxy';
define(['js/softphone/' + softphoneAPIType + '/softphone.api' + $E.jsv,
    "js/softphone/callstate",
    "js/softphone/agentstate",
    "js/softphone/agentmode",
    "js/softphone/ctistatus",
    "js/softphone/timer",
    "js/softphone/calltype"], function (SoftphoneAPI, CallState, AgentState, AgentMode, CTIStatus, Timer, CallType) {

    const EVENTS = {
        QUERY_AUX_EVT: '__sp_query_aux__',
        AUX_TIMEOUT_EVT: '__sp_aux_timeout__',
        STATE_CHANGE_EVT: '__sp_state_change__',
        SOFTPHONE_AGENT_LOGINED: 'SOFTPHONE_AGENT_LOGINED',
        INITIALIZED: '__sp_initialized__'
    };

    const Softphone = function () {
        SoftphoneAPI.apply(this, arguments);
        this.currentCallInfo = undefined;
        this.currentCallState = 0;
        this.currentAgentState = 0;
        this.currentAgentMode = 0;
        this.currentBreakType = -1;
        this.agentConferenced = false;
        this.agentTransfered = false;
        this.startInitTransfer = false;
        this.startInitConference = false;
        this.agentLogined = false;
        this.notClearNumberWhenECTUNKNOW = false;
        this.transferOnDialingHold = false;
        this.currentAgentStateText = "";
        this.currentCTIStatus = 0;
        this.baseStartTime = 1;
        this.extension = "";
        this.agentId = "";
        this.currentCallNumber = "";

        this.totalIB = 0;
        this.totalOB = 0;
        this.totalIBAnswered = 0;
        this.totalOBReached = 0;
        this.totalIBDuration = 0;
        this.totalOBDuration = 0;
        this.totalIBDisplay = "";
        this.totalOBDisplay = "";

        this.makeCallEnabled = true;
        this.makeCallVisible = true;
        this.releaseCallEnabled = true;
        this.releaseCallVisible = true;
        this.releaseCallConfirm = false;//点击挂断电话时候是不是要弹出确认对话框
        this.holdEnabled = true;
        this.holdVisible = true;
        this.initConferenceEnabled = true;
        this.initConferenceVisible = true;
        this.initTransferEnabled = true;
        this.initTransferVisible = true;
        this.reconnectEnabled = true;
        this.reconnectVisible = true;
        this.directTransferEnabled = true;
        this.directTransferVisible = true;
        this.notReadyEnabled = true;
        this.notReadyVisible = true;
        this.readyEnabled = true;
        this.readyVisible = true;
        this.breakEnabled = true;
        this.breakVisible = true;
        this.muteEnabled = true;
        this.muteVisible = false;
        this.nightRingEnabled = true;
        this.nightRingVisible = false;
        this.hideCallNumber = false;
        this.initTransferIVREnabled = false;
        this.initTransferIVRVisible = false;
        this.initTransferQueueEnabled = false;
        this.initTransferQueueVisible = false;

        this.auxMap = {};
        this.statusRelations = {};
        this.agentStateAlert = {};
        this.stateLastTime = new Date();
        //登录对话框
        this.loginDialog = undefined;
        //小修原因选择对话框
        this.breakDialog = undefined;
        //PDS市场活动选择对话框
        this.pdsDialog = undefined;
        //ctitype选择对话框
        this.ctiTypeDialog = undefined;

        //通话时长更新定时器
        this.callTimeTimer = undefined;
        //来电号码闪烁定时器
        this.callNumBlinkTimer = undefined;
        //状态持续时长定时器
        this.stateLastTimer = undefined;
        //应答按钮闪烁定时器
        this.answerBtnBlinkTimer = undefined;

        //电话当前项目
        this.currentProject = undefined;
        //拨打号码的历史
        this.aniQueue = [];
        this.aniQueueLength = 5;
        //初始化信息，调用getIniInfo后获取
        this.iniInfo = {};
        // 是否限制小修
        this.auxLimit = false;
        // 小修时间限制(秒数)
        this.auxTimeout = 0;
        this.auxTimer = null;
        // 是否保存auxdetail
        this.saveAuxDetail = false;
        this.auxDetail = {};
        // 初始化状态
        this.initialized = false;

        this.spItems = [];

        this.mediaType = '';
    };

    //Softphone继承与SoftphoneAPI
    const F = function () {};
    F.prototype = SoftphoneAPI.prototype;
    Softphone.prototype = new F();
    Softphone.prototype.constructor = Softphone;

    /**
     * 添加自定义软电话按钮
     * @param id  按钮id 不可重复
     * @param title 按钮上的文字描述
     * @param handler 点击按钮后的行为
     * @param options (可选) 相关选项:
     *        {
     * 			needLogin : true, //是否需要登录后才可点击
     * 			needCallStart : true, //是否需要电话开始后才可以点击
     * 			needCallEstablish : true //是否需要电话接通后才可以点击
     * 		}
     */
    Softphone.prototype.addCustomButton = function (id, title, handler, options) {
        const softphone = this;
        const customBtnDom = $('#c_softphone .sp_custom_btn[data-id=' + id + ']');
        if (customBtnDom.length === 0) {
            $('<button data-id="' + id + '" class="sp_custom_btn" title="' + title + '">' + title + '</button>').click($F.debounce(function () {
                if ($.isFunction(handler)) {
                    handler();
                }
            }, 1000)).appendTo('#c_softphone');
            if (options) {
                if (options.needLogin) {//必须登录才可以使用
                    $E.events.register(EVENTS.SOFTPHONE_AGENT_LOGINED, 'CUSTOM_BUTTON_' + id, function (logined) {
                        setBtnEnable(customBtnDom, logined);
                    });
                    setBtnEnable(customBtnDom, softphone.agentLogined);
                }
                if (options.needCallStart) {//必须电话开始才可以使用
                    $E.events.register($CONST.CTIEvent.CTI_ONCALLSTART, 'CUSTOM_BUTTON_' + id, function () {
                        setBtnEnable(customBtnDom, true);
                    });
                    $E.events.register($CONST.CTIEvent.CTI_ONCALLEND, 'CUSTOM_BUTTON_' + id, function () {
                        setBtnEnable(customBtnDom, false);
                    });
                    setBtnEnable(customBtnDom, false);
                } else if (options.needCallEstablish) {//必须电话接起才可以使用
                    $E.events.register($CONST.CTIEvent.CTI_ONCALLESTABLISH, 'CUSTOM_BUTTON_' + id, function () {
                        setBtnEnable(customBtnDom, true);
                    });
                    $E.events.register($CONST.CTIEvent.CTI_ONCALLEND, 'CUSTOM_BUTTON_' + id, function () {
                        setBtnEnable(customBtnDom, false);
                    });
                    setBtnEnable(customBtnDom, false);
                }
            }
        } else {
            $F.log('Softphone - addCustomButton', 'Duplicate id found [' + id + ']');
        }
    };

    /**
     * 根据不同的NeedQueueExt获取queue
     * 2--登录前先通过工号从数据库获取队列，3--登录前通过CTI接口获取队列；4--登录后通过数据库获取队列，5--登录后通过CTI获取队列
     */
    const fetchQueues = function (agentId, callback) {
        const project = softphone.getCurrentProject();
        const needQueueExt = $F.parseInt(softphone.iniInfo.NeedQueueExt);
        if (needQueueExt === 2) {
            let queues = [],
                ret = project.commonQuerySync('softphone.agentqueues.query', [agentId]);
            if (ret && ret.value[0].count > 0) {
                var retArr = $F.makeJsonArray(ret.value[0]);
                if (retArr && retArr.length > 0) {
                    retArr.forEach(function (q) {
                        queues.push({
                            label: q.QUEUENAME,
                            value: q.QUEUENUM
                        });
                    })
                }
            }
            callback(queues);
        } else if (needQueueExt === 3) {
            softphone.simpleCommonCall('getagentqueues', agentId, function (retArr) {
                let queues = [];
                if (retArr && retArr.length > 0) {
                    retArr.forEach(function (q) {
                        queues.push({
                            label: q.QUEUENAME,
                            value: q.QUEUENUM
                        });
                    });
                }
                callback(queues);
            });
        } else if (needQueueExt === 4) {
            callback();
        } else if (needQueueExt === 5) {
            callback();
        } else {
            callback();
        }
    };

    //初始化软电话
    const doInitSoftphone = function (softphone, project, params, callback) {
        softphone.initSoftphone(params, function () {
            softphone.getCallStat(function (callStat) {
                softphone.refreshCallStat(callStat);
            });

            var IOBVIS = $F.parseInt(project.getParam("IOBVIS"));
            if (IOBVIS === 1) {
                $("#c_softphone .sp_stat").show();
            }
            softphone.hideCallNumber = $F.parseInt(project.getParam("HDCANO")) === 1;
            softphone.auxLimit = $F.parseInt(project.getParam("AUXLMT")) === 1;
            softphone.saveAuxDetail = $F.parseInt(project.getParam("SAVAUX")) === 1;

            //init aux map
            var data = project.commonQuerySync("Softphone.auxcode.query", []);
            if (data && data.value[0].count > 0) {
                for (let i = 0; i < data.value[0].count; i++) {
                    var auxId = data.value[0].fields[i][0];
                    softphone.auxMap[auxId] = data.value[0].fields[i][1];
                    $(BUTTONS.BREAK_TYPE_SELECT).append("<option value='" + auxId + "' data-needcomments='" + data.value[0].fields[i][2] + "'>" + data.value[0].fields[i][1] + "</option>");
                }
                $(BUTTONS.BREAK_TYPE_SELECT).val(-1).change(function () {
                    var breakSelect = $(this),
                        selectedOption = breakSelect.find("option:selected"),
                        breakType = this.value,
                        breakTypeText = selectedOption.text();
                    if (softphone.auxLimit) {// 如果系统参数配置了控制小修，则发出一个事件，不做其他处理，让动态页面自己处理
                        project.events.notify(EVENTS.QUERY_AUX_EVT, {"breakType": breakType});
                    } else {
                        if (selectedOption.attr('data-needcomments') == 1) {
                            if (!softphone.breakDialog) {
                                softphone.breakDialog = $F.createDialog($('<div class="sp_break_dialog">' + '<div>' +
                                    '<span>' + $F.lang('softphone.comments') + ':</span><textarea maxlength="200" class="sp_break_comments"></textarea>' +
                                    '</div>' + '<span class="sp_break_comments_number" style="float: right; color: #999;">0/200</span>' +
                                    '</div>'), {
                                    title: $F.lang('softphone.breaks'),
                                    contentCSS: {
                                        'padding' : '15px 10px 0 10px',
                                        'overflow' : 'auto'
                                    },
                                    onSubmit: function () {
                                        var auxComments = softphone.breakDialog.find(".sp_break_comments").val();
                                        if (!auxComments) {
                                            return $F.alert($F.lang('softphone.breakCommentsAlert'));
                                        }
                                        breakType = $(BUTTONS.BREAK_TYPE_SELECT).val();
                                        breakTypeText = $(BUTTONS.BREAK_TYPE_SELECT).find("option:selected").text();
                                        softphone.simpleCommonCall("button.click", "notreadycode_" + breakType);
                                        softphone.currentBreakType = breakType;
                                        softphone.setBreakTypeLabelText(breakTypeText);
                                        softphone.setAuxDetail(breakType, auxComments);
                                        $F.dialogClose(softphone.breakDialog);
                                    },
                                    onClose: function () {
                                        $(BUTTONS.BREAK_TYPE_SELECT).val(softphone.currentBreakType);
                                    }
                                });
                                if (softphone.breakDialog.find(".sp_break_comments")[0] && softphone.breakDialog.find(".sp_break_comments_number")[0]) {
                                    softphone.breakDialog.find(".sp_break_comments")[0].oninput = function(val) {
                                        softphone.breakDialog.find(".sp_break_comments_number")[0].innerHTML = val.target.value.length + '/200'
                                    }
                                }
                            } else {
                                softphone.breakDialog.find(".sp_break_comments").val("");
                                if(softphone.breakDialog.find(".sp_break_comments_number")[0]) {
                                    softphone.breakDialog.find(".sp_break_comments_number")[0].innerHTML = '0/200'
                                }
                                Helper.masker.show(softphone.breakDialog);
                            }
                        } else {
                            softphone.simpleCommonCall("button.click", "notreadycode_" + breakType);
                            softphone.currentBreakType = breakType;
                            softphone.setBreakTypeLabelText(breakTypeText);
                            softphone.setAuxDetail(breakType, '');
                        }
                    }
                })
            }


            var staffBean = project.getStaffById($E.staff.id).bean;
            data = project.commonQuerySync("Aux.TimeoutLimit.Get", [$E.staff.current.groupId, staffBean.BEAREA_ID || '', $E.staff.id]);
            if (data && data.value[0].count > 0) {
                softphone.auxTimeout = data.value[0].fields[0][0];
            }

            var SPOPEN = project.getParam("SPOPEN");
            $F.log("Softphone.init", "Set enabled of softphone operations : " + SPOPEN);
            if (!$F.isEmpty(SPOPEN)) {
                var operationsEnabled = SPOPEN.split("|");
                if (operationsEnabled && operationsEnabled.length > 0) {
                    operationsEnabled.forEach(function (operationEnabledStr) {
                        if (operationEnabledStr.indexOf("=") > 0) {
                            let operationName = operationEnabledStr.substr(0, operationEnabledStr.indexOf("="));
                            let operationEnabled = $F.parseInt(operationEnabledStr.substr(operationEnabledStr.indexOf("=") + 1));
                            if ($F.equalsIgnoreCase(operationName, "makeCall")) {
                                softphone.makeCallEnabled = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "addressbook")) {
                                softphone.addressbookEnabled = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "releaseCall")) {
                                softphone.releaseCallEnabled = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "releaseCallConfirm")) {
                                softphone.releaseCallConfirm = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "hold")) {
                                softphone.holdEnabled = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "initConference")) {
                                softphone.initConferenceEnabled = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "initTransfer")) {
                                softphone.initTransferEnabled = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "reconnect")) {
                                softphone.reconnectEnabled = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "directTransfer")) {
                                softphone.directTransferEnabled = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "notReady")) {
                                softphone.notReadyEnabled = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "ready")) {
                                softphone.readyEnabled = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "break")) {
                                softphone.breakEnabled = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "makeCallVisible")) {
                                softphone.makeCallVisible = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "releaseCallVisible")) {
                                softphone.releaseCallVisible = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "holdVisible")) {
                                softphone.holdVisible = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "initConferenceVisible")) {
                                softphone.initConferenceVisible = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "initTransferVisible")) {
                                softphone.initTransferVisible = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "reconnectVisible")) {
                                softphone.reconnectVisible = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "directTransferVisible")) {
                                softphone.directTransferVisible = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "notReadyVisible")) {
                                softphone.notReadyVisible = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "readyVisible")) {
                                softphone.readyVisible = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "breakVisible")) {
                                softphone.breakVisible = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "muteVisible")) {
                                softphone.muteVisible = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "muteEnabled")) {
                                softphone.muteEnabled = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "nightRingVisible")) {
                                softphone.nightRingVisible = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "nightRingEnabled")) {
                                softphone.nightRingEnabled = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "initTransferIVRVisible")) {
                                softphone.initTransferIVRVisible = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "initTransferQueueVisible")) {
                                softphone.initTransferQueueVisible = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "initTransferIVR")) {
                                softphone.initTransferIVREnabled = operationEnabled === 1;
                            } else if ($F.equalsIgnoreCase(operationName, "initTransferQueue")) {
                                softphone.initTransferQueueEnabled = operationEnabled === 1;
                            }
                        }
                    });
                }
            }


            var SPSHOW = project.getParam("SPSHOW");
            //SPSHOW，0为隐藏，1展示
            // const setBtnShow = function () {
            $F.log("Softphone.init", "Set visiblity of softphone operations : " + SPSHOW);
            if (!$F.isEmpty(SPSHOW)) {
                var operationsVisiblity = SPSHOW.split("|");
                if (operationsVisiblity && operationsVisiblity.length > 0) {
                    operationsVisiblity.forEach(function (operationVisiblityStr) {
                        if (operationVisiblityStr.indexOf("=") > 0) {
                            let operationName = operationVisiblityStr.substr(0, operationVisiblityStr.indexOf("="));
                            let operationVisiblity = $F.parseInt(operationVisiblityStr.substr(operationVisiblityStr.indexOf("=") + 1));
                            if ($F.equalsIgnoreCase(operationName, "makeCall")) {
                                softphone.makeCallVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "hold")) {
                                softphone.holdVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "retrieve")) {
                                softphone.retrieveVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "initConference")) {
                                softphone.initConferenceVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "completeConference")) {
                                softphone.completeConferenceVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "initTransfer")) {
                                softphone.initTransferVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "completeTransfer")) {
                                softphone.completeTransferVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "reconnect")) {
                                softphone.reconnectVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "directTransfer")) {
                                softphone.directTransferVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "notReady")) {
                                softphone.notReadyVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "ready")) {
                                softphone.readyVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "break")) {
                                softphone.breakVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "mute")) {
                                softphone.muteVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "unmute")) {
                                softphone.unmuteVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "nightRingOn")) {
                                softphone.nightRingOnVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "nightRingOff")) {
                                softphone.nightRingOffVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "login")) {
                                softphone.loginVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "logout")) {
                                softphone.logoutVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "numContainer")) {
                                softphone.numContainerVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "numKeyboardSwitcher")) {
                                softphone.numKeyboardSwitcherVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "numKeyboardContainer")) {
                                softphone.numKeyboardContainerVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "numKeyboard")) {
                                softphone.numKeyboardVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "videoAnswer")) {
                                softphone.videoAnswerVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "videoRelease")) {
                                softphone.videoReleaseVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "transferToIvr")) {
                                softphone.transferToIvrVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "transferToQueue")) {
                                softphone.transferToQueueVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "expands")) {
                                softphone.expandsVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "breakTypeSelect")) {
                                softphone.breakTypeSelectVisiblein = operationVisiblity === 0;
                            } else if ($F.equalsIgnoreCase(operationName, "answer")) {
                                softphone.answerVisiblein = operationVisiblity === 0;
                            }
                        }
                    });
                }
            }
            // }

            //初始化按钮状态
            softphone.setBtnStatus();
            // 收到打开视频聊天界面事件后，显示视频接起和挂断按钮
            $E.events.register($CONST.SoftphoneEvent.VIDEO_CLICKED, 'Softphone', function() {
                hideBtn($(BUTTONS.VIDEO_ANSWER));
                hideBtn($(BUTTONS.VIDEO_RELEASE));
            });

            //注册softphone事件 callback
            softphone.addEventListener(function (data, ev) {
                if (data.type === "SCTIEvent") {
                    //处理SCTI消息
                    softphone.handleSCTIEvents(data.msg);

                    //通知框架相关SCTI事件
                    /*
                    	sfInfo 包括属性
                    	@type {{ani: (param.ANI|*), dnis: (param.DNIS|*), agentid: *, extension: *, agentstate: *, evtdetail: *, calltype: *, attachdatadisplay: *}}
                     */
                    softphone.notifySCTIEvents(data.msg, data.sfInfo);
                } else if (data.type === "CTIEvent") {
                    //响应CTIEvent，主要就是通知框架相关CTI事件
                    softphone.handleCTIEvents(data.msg);
                } else if (data.type === 'inited') {
                    if ($E.query !== 'woa' && $E.query !== 'crm') {
                        softphone.callSoftphoneLoginInfo(softphone.getCurrentProject());
                        softphone.setJSService(softphone.getCurrentProject());
                        // 重置软电话状态
                        softphone.reset();
                    }
                }
            });

            //softphone logon
            $(BUTTONS.LOGIN).click($F.debounce(function () {
                if (project.getParam('SPCULO') === '1') { // 是否自定义登录，如果是软电话只发出一个事件，不去实际显示登录弹窗
                    project.events.notify($CONST.SoftphoneEvent.LOGIN_CLICKED);
                    if (!softphone.checkCouldReady()) {
                        return $F.alert($F.lang('softphone.cannotLogin'));
                    }
                    return;
                }
                if (!softphone.checkCouldReady()) {
                    return $F.alert($F.lang('softphone.cannotLogin'));
                }
                softphone.setBtnStatus();

                if (!softphone.loginDialog) {
                    let staff = project.getStaffById($E.staff.id);
                    let agentId = $E.staff.agentId,
                        extension = staff.bean ? staff.bean.EXTENSION : '',
                        queue = $.cookie('softphone.login.queue') || '';
                    softphone.getIniInfo(function (data) {
                        $F.log('softphone - getIniInfo', JSON.stringify(data));//NeedAgentID: "1", NeedPassword: "0", NeedExtension: "1", AgentID: "5005", Extension: "8005"
                        if (data.code === -1) {
                            return $F.alert(data.message);
                        }
                        softphone.iniInfo = data;
                        softphone.iniInfo.NeedQueueExt = $F.parseInt(data.NeedQueueExt);
                        softphone.iniInfo.NeedAgentID = $F.parseInt(data.NeedAgentID);
                        softphone.iniInfo.NeedQueue = $F.parseInt(data.NeedQueue);
                        softphone.iniInfo.NeedExtension = $F.parseInt(data.NeedExtension);
                        softphone.iniInfo.NeedPDS = $F.parseInt(data.NeedPDS);
                        softphone.iniInfo.NeedPosition = $F.parseInt(data.NeedPosition);
                        softphone.iniInfo.NeedPassword = $F.parseInt(data.NeedPassword);

                        extension = extension || data.Extension;

                        const setupQueueCombox = function (queueCombox, queues, queue, project) {
                            let SQATSL = $F.parseInt(project.getParam('SQATSL'));
                            queueCombox.setData(queues);
                            if (SQATSL === 1) {
                                let allQueues = [];
                                queues.forEach(q => {
                                    allQueues.push(q.value);
                                });
                                queueCombox.val(allQueues);
                                queueCombox.disable(true);
                            } else {
                                if (queue) {
                                    queueCombox.val(queue.split(';'));
                                }
                            }
                        };

                        const doLogin = function(agentId, extension, queue, position, password, pdsEnable) {
                            var busyId = $F.busyShow($F.lang('softphone.logining'));
                            softphone.login({
                                agentId: agentId,
                                extension: extension,
                                queue: queue,
                                position: position,
                                password: password,
                                pds: {
                                    pdsenable: pdsEnable
                                }
                            }, function (result, msg) {
                                $F.log('Softphone - login', 'Login result: ' + result);
                                $F.busyHide(busyId);
                                if (!result) {
                                    $F.log('Softphone - login', 'Error msg: ', msg);
                                    $F.alert($F.lang('softphone.loginFailed') + (msg && msg.errormsg ? (" : " + msg.errormsg) : ""));
                                } else {
                                    $F.dialogClose(softphone.loginDialog);
                                    softphone.extension = extension;
                                    softphone.agentId = agentId;
                                    if (softphone.iniInfo.NeedQueueExt === 5) {
                                        //再要选队列
                                        softphone.showQueueSelectDialog();
                                    } else {
                                        softphone.queue = queue;
                                    }
                                    $.cookie('softphone.login.queue', queue, {
                                        expires: 30
                                    });
                                    softphone.showPDSLoginDialog();
                                }
                            });
                        };

                        const showLoginDialog = function (queues) {
                            var dialog = $('<div class="sp_login_dialog"></div>');
                            var nonAutoCompleteForm = $('<form autocomplete="off"></form>').appendTo(dialog);
                            nonAutoCompleteForm.append('<div style="display: ' + (softphone.iniInfo.NeedPDS >= 1 ? 'block' : 'none') + ';"><span style="display:inline-block;margin-right: 5px;">' + $F.lang('softphone.pds') + ':</span><input ' + (softphone.iniInfo.NeedPDS === 2 ? 'disabled' : '') + ' class="sp_login_pds" type="checkbox" value=""></div>');
                            nonAutoCompleteForm.append('<div style="display: ' + (softphone.iniInfo.NeedAgentID === 0 ? 'none' : 'block') + ';"><span style="display:inline-block">' + $F.lang('softphone.agentId') + ':</span><input ' + (softphone.iniInfo.NeedAgentID === 2 ? 'disabled' : '') + ' class="sp_login_agentId" type="text" value="' + agentId + '"></div>');
                            nonAutoCompleteForm.append('<div style="display: ' + (softphone.iniInfo.NeedExtension === 0 ? 'none' : 'block') + ';"><span style="display:inline-block">' + $F.lang('softphone.extension') + ':</span><input ' + (softphone.iniInfo.NeedExtension === 2 ? 'disabled' : '') + ' class="sp_login_extension" type="text" value="' + extension + '"></div>');

                            var queueDom = '<div style="display: ' + (softphone.iniInfo.NeedQueue === 0 ? 'none' : 'block') + ';"><span style="display:inline-block">' + $F.lang('softphone.queue') + ':</span>';
                            if (softphone.iniInfo.NeedQueueExt === 2 || softphone.iniInfo.NeedQueueExt === 3) {
                                queueDom += '<div class="sp_login_queue" style="width: 168px;margin-left: 3px;margin-top: 5px;margin-bottom: 3px;"></div></div>';
                                queueDom = $(queueDom);
                                var queueCombox = $(".sp_login_queue", queueDom).wisCombox({
                                    tip: $F.lang('softphone.queueSelect'),
                                    maxHeight: 200,
                                    multi: !!softphone.iniInfo.QueueMultiSelect
                                });
                                setupQueueCombox(queueCombox, queues, queue, project);

                                $('.sp_login_agentId', nonAutoCompleteForm).blur(function () {
                                    var agentId = $(this).val();
                                    fetchQueues(agentId, function (queues) {
                                        setupQueueCombox(queueCombox, queues, queue, project);
                                    });
                                });
                            } else if (softphone.iniInfo.NeedQueueExt === 4 || softphone.iniInfo.NeedQueueExt === 5) {
                                queueDom = '';
                            } else {
                                queueDom += '<input ' + (softphone.iniInfo.NeedQueue === 2 ? 'disabled' : '') + ' class="sp_login_queue" type="text" value="' + queue + '"></div>';
                            }
                            nonAutoCompleteForm.append(queueDom);

                            nonAutoCompleteForm.append('<div style="display: ' + (softphone.iniInfo.NeedPosition === 0 ? 'none' : 'block') + ';"><span style="display:inline-block">' + $F.lang('softphone.position') + ':</span><input ' + (softphone.iniInfo.NeedPosition === 2 ? 'disabled' : '') + ' class="sp_login_position" type="text"></div>');
                            nonAutoCompleteForm.append('<div style="display: ' + (softphone.iniInfo.NeedPassword === 0 ? 'none' : 'block') + ';"><span style="display:inline-block">' + $F.lang('softphone.password') + ':</span><input ' + (softphone.iniInfo.NeedPassword === 2 ? 'disabled' : '') + ' class="sp_login_password" type="password" autocomplete="off"></div>');

                            softphone.loginDialog = $F.createDialog(dialog, {
                                title: $F.lang('softphone.loginSoftphone'),
                                onSubmit: function () {
                                    if (softphone.available()) {
                                        let agentId = $(".sp_login_dialog .sp_login_agentId").val(),
                                            extension = $(".sp_login_dialog .sp_login_extension").val(),
                                            position = $(".sp_login_dialog .sp_login_position").val(),
                                            password = (softphone.iniInfo.NeedPassword === 0 || softphone.iniInfo.NeedPassword === 2) ? '' : $(".sp_login_dialog .sp_login_password").val(), // 不显示或者不可用时候，密码总归是空字符串，避免chrome的autocomplete自动填上密码
                                            pdsEnable = $(".sp_login_dialog .sp_login_pds").prop('checked'),
                                            queue;

                                        if (softphone.iniInfo.NeedQueueExt === 2 || softphone.iniInfo.NeedQueueExt === 3) {
                                            var selectQueues = $(".sp_login_dialog .sp_login_queue").data('wisCombox').val(),
                                                queues = [], queuesDesc = [];
                                            if (selectQueues && selectQueues.length > 0) {
                                                selectQueues.forEach(function (q) {
                                                    queues.push(q.value);
                                                    queuesDesc.push(q.label);
                                                });
                                                queue = queues.join(';');
                                                softphone.queueDesc = queuesDesc.join(';');
                                            }
                                        } else if (softphone.iniInfo.NeedQueueExt === 4 || softphone.iniInfo.NeedQueueExt === 5) {

                                        } else {
                                            queue = $(".sp_login_dialog .sp_login_queue").val();
                                        }

                                        doLogin(agentId, extension, queue, position, password, pdsEnable);
                                    } else {
                                        $F.alert($F.lang('softphone.cannotConnectLocalProxy'), function () {
                                            $F.dialogClose(softphone.loginDialog);
                                        });
                                    }
                                }
                            });
                        };

                        fetchQueues(agentId, function (queues) {
                            if ($F.parseInt(project.getParam("SPALOG")) === 1) {
                                doLogin(agentId, extension, '', '', '', false);
                            } else {
                                showLoginDialog(queues);
                            }
                        });
                    });

                } else {
                    //$F.dialogOpen(loginDialog);
                    Helper.masker.show(softphone.loginDialog);
                }
            }, 1000));

            //softphone logout
            $(BUTTONS.LOGOUT).click($F.debounce(function () {
                $F.log('softphone - logout', 'Logout button clicked.');
                var project = softphone.getCurrentProject();
                if (project.workDuration) {
                    $F.alert(i18n.softphone.prohibitLogoutDuringWork);
                } else {
                    if (softphone.currentCallState === CallState.ECT_DIALING || softphone.currentCallState === CallState.ECT_RINGING
                        || softphone.currentCallState === CallState.ECT_TALKING || softphone.currentCallState === CallState.ECT_HOLD
                        || softphone.currentCallState === CallState.ECT_DIALINGHOLD || softphone.currentCallState === CallState.ECT_TALKINGHOLD) {
                        $F.confirm(i18n.softphone.confirmLogout, function () {
                            softphone.logout(ret => {
                                $F.log('softphone - logout', 'Logout ret: ' + ret);
                                if (ret) {
                                    softphone.setBreakTypeLabelText('');
                                    $("#c_softphone .sp_status").html($F.lang('softphoneEle.sp_status'));
                                }
                            });
                        });
                    } else {
                        softphone.logout(ret => {
                            $F.log('softphone - logout', 'Logout ret: ' + ret);
                            if (ret) {
                                softphone.setBreakTypeLabelText('');
                                $("#c_softphone .sp_status").html($F.lang('softphoneEle.sp_status'));
                            }
                        });
                    }
                }
            }, 1000));


            $(BUTTONS.MAKE_CALL).click($F.debounce(function () {
                var number = $(BUTTONS.ANI).val();
                if ($F.isEmpty(number)) {
                    $F.alert(i18n.softphone.pleaseInputNumber);
                    return;
                }
                softphone.putToAniQueue(number);
                softphone.makeCall(number);
            }, 1000));
            $(BUTTONS.ANSWER).click($F.debounce(function () {
                softphone.answerCall();
                // if (softphone.mediaType === 'video') {
                //     setBtnShow();
                // }
                $('.sp_call .sp_block').html($F.lang('softphoneEle.sp_callNumber'));
            }, 1000));
            $(BUTTONS.RELEASE).click($F.debounce(function () {
                if (softphone.releaseCallConfirm) {
                    $F.confirm($F.lang('softphone.handoutConfirm'), function () {
                        softphone.releaseCall();
                    });
                } else {
                    softphone.releaseCall();
                }
            }, 1000));

            // 这两个转接到IVR和转接到队列的按钮，仅仅是发出事件，具体逻辑由动态页面上监听事件的地方去处理
            $(BUTTONS.TRANSFER_TO_IVR).click($F.debounce(function () {
                softphone.fireTransferToIVR();
            }, 1000));
            $(BUTTONS.TRANSFER_TO_QUEUE).click($F.debounce(function () {
                softphone.fireTransferToQueue();
            }, 1000));

            $(BUTTONS.HOLD).click($F.debounce(function () {
                softphone.holdCall();
            }, 1000));

            $(BUTTONS.RETRIEVE).click($F.debounce(function () {
                softphone.retrieveCall();
            }, 2000));

            $(BUTTONS.INIT_CONFERENCE).click($F.debounce(function () {
                if (softphone.mediaType === 'video') {
                    $F.log("Softphone.InitTransfer", "InitConference btn clicked, fire SoftphoneEvent.INIT_CONFERENCE while mediaType is video");
                    softphone.getCurrentProject().events.notify($CONST.SoftphoneEvent.INIT_CONFERENCE);
                } else {
                    const number = $(BUTTONS.ANI).val();
                    $F.log("Softphone.InitConference", "InitConference btn clicked.");
                    if (!number) {
                        if (transferType) {
                            softphone.getCurrentProject().events.notify($CONST.SoftphoneEvent.INIT_CONFERENCE);
                            return
                        } else {
                            $F.alert($F.lang('softphone.pleaseInputNumber'));
                            return
                        }
                    } else {
                        softphone.putToAniQueue(number);
                        softphone.initConference(number);
                    }
                }
            }, 1000));
            $(BUTTONS.COMPLETE_CONFERENCE).click($F.debounce(function () {
                $F.log("Softphone.CompleteConference", "CompleteConference btn clicked.");
                $(BUTTONS.ANI).val("");
                softphone.completeConference();
            }, 1000));

            const transferType = project.getParam('SPTRAN');

            $(BUTTONS.INIT_TRANSFER).click($F.debounce(function () {
                if (softphone.mediaType === 'video') {
                    $F.log("Softphone.InitTransfer", "InitTransfer btn clicked, fire SoftphoneEvent.INIT_TRANSFER while mediaType is video");
                    softphone.getCurrentProject().events.notify($CONST.SoftphoneEvent.INIT_TRANSFER);
                } else {
                    const number = $(BUTTONS.ANI).val();
                    $F.log("Softphone.InitTransfer", "InitTransfer btn clicked.");
                    if (!number) {
                        if (transferType) {
                            softphone.getCurrentProject().events.notify($CONST.SoftphoneEvent.INIT_TRANSFER, 'INIT_TRANSFER');
                            return
                        } else {
                            $F.alert($F.lang('softphone.pleaseInputNumber'));
                            return
                        }
                    } else {
                        softphone.putToAniQueue(number);
                        softphone.initTransfer(number);
                    }
                }
            }, 1000));
            $(BUTTONS.COMPLETE_TRANSFER).click($F.debounce(function () {
                $F.log("Softphone.CompleteTransfer", "CompleteTransfer btn clicked.");
                $(BUTTONS.ANI).val("");
                softphone.completeTransfer();
            }, 1000));
            $(BUTTONS.DIRECT_TRANSFER).click($F.debounce(function () {
                const number = $(BUTTONS.ANI).val();
                $F.log("Softphone.MuteTransfer", "MuteTransfer btn clicked.");
                if (!number) {
                    if (transferType) {
                        softphone.getCurrentProject().events.notify($CONST.SoftphoneEvent.INIT_TRANSFER, 'DIRECT_TRANSFER');
                        return
                    } else {
                        $F.alert($F.lang('softphone.pleaseInputNumber'));
                        return
                    }
                } else {
                    softphone.putToAniQueue(number);
                    softphone.muteTransfer(number);
                }
            }, 1000));
            $(BUTTONS.RECONNECT).click($F.debounce(function () {
                $F.log("Softphone.Reconnect", "Reconnect btn clicked.");
                softphone.reconnect();
            }, 1000));

            $(BUTTONS.READY).click($F.debounce(function () {
                $F.log("Softphone.Ready", "Ready btn clicked.");
                if (softphone.checkCouldReady()) {
                    softphone.setBreakTypeLabelText("");
                    softphone.ready();
                } else {
                    $F.alert($F.lang('softphone.cannotReady'));
                    $F.log("Softphone.Ready", "Can't ready right now.");
                }
            }, 1000));
            $(BUTTONS.NOT_READY).click($F.debounce(function () {
                $F.log("Softphone.NotReady", "NotReady btn clicked.");
                softphone.setBreakTypeLabelText("");
                softphone.notReady();
            }, 1000));
            $(BUTTONS.BREAK).click($F.debounce(function () {
                $F.log("Softphone.Break", "Break btn clicked.");
                if (!checkBtnAvailable('BREAK')) return;
                if (softphone.auxLimit) {// 如果系统参数配置了控制小修，则发出一个事件，不做其他处理，让动态页面自己处理
                    project.events.notify(EVENTS.QUERY_AUX_EVT, {"breakType": ''});
                } else {
                    softphone.setBreakTypeLabelText("");
                    if (softphone.currentCallState === CallState.ECT_TALKING) {
                        $(BUTTONS.BREAK).addClass("request");
                    }
                    softphone.setAuxDetail('-1', '');
                    softphone.breaks();
                }
            }, 1000));

            window.addEventListener('message', function (e) {
                if (e.data.module === 'softphone') {
                    if (e.data.type === 'ready') {
                        // showBtn($(BUTTONS.VIDEO_ANSWER));
                        // showBtn($(BUTTONS.VIDEO_RELEASE))
                    } else if (e.data.type === 'leave') {
                        $(BUTTONS.VIDEO_ANSWER).hide();
                        $(BUTTONS.VIDEO_RELEASE).hide();
                    }
                    if (e.data.ringBtn === 'start') {
                        $(BUTTONS.VIDEO_ANSWER).addClass('breath');
                    } else if (e.data.ringBtn === 'end') {
                        $(BUTTONS.VIDEO_ANSWER).removeClass('breath');
                    }
                }
            }, false);
            $(BUTTONS.VIDEO_ANSWER).click($F.debounce(function () {
                window.frames['videoChat'].postMessage({type: 'ringCall', msg: '接听'}, "*");
            }, 1000));
            $(BUTTONS.VIDEO_RELEASE).click($F.debounce(function () {
                window.frames['videoChat'].postMessage({type: 'G18', msg: '挂断'}, "*");
            }, 1000));

            //初始化mute按钮
            //下面两行全部注释好像也不会出现问题
            softphone.muteVisible && showBtn($(BUTTONS.MUTE));
            softphone.nightRingVisible && showBtn($(BUTTONS.NIGHT_RING_ON));


            $(BUTTONS.MUTE).click($F.debounce(function () {
                $F.log("Softphone.Mute", "Mute btn clicked.");
                softphone.mute(function (d) {
                    if (d) {
                        $F.log("Softphone.Mute", "Mute success.");
                        softphone.isMute = true;
                    } else {
                        $F.log("Softphone.Mute", "Mute fail.");
                    }
                });
            }, 1000));
            $(BUTTONS.UNMUTE).click($F.debounce(function () {
                $F.log("Softphone.UnMute", "UnMute btn clicked.");
                softphone.unMute(function (d) {
                    if (d) {
                        $F.log("Softphone.UnMute", "UnMute success.");
                        softphone.isMute = false;
                    } else {
                        $F.log("Softphone.UnMute", "UnMute fail.");
                    }
                });
            }, 1000));
            $(BUTTONS.NIGHT_RING_ON).click($F.debounce(function () {
                $F.log("Softphone.NIGHT_RING_ON", "NIGHT_RING_ON btn clicked.");
                softphone.simpleCommonCall('button.click', 'nightringon');
                hideBtn($(BUTTONS.NIGHT_RING_ON));
                showBtn($(BUTTONS.NIGHT_RING_OFF));
            }, 1000));
            $(BUTTONS.NIGHT_RING_OFF).click($F.debounce(function () {
                $F.log("Softphone.NIGHT_RING_ON", "NIGHT_RING_OFF btn clicked.");
                softphone.simpleCommonCall('button.click', 'nightringoff');
                hideBtn($(BUTTONS.NIGHT_RING_OFF));
                showBtn($(BUTTONS.NIGHT_RING_ON));
            }, 1000));

            $(BUTTONS.EXPANDS).click(function () {
                if($(this).hasClass('expand')) {
                    $(this).removeClass('expand')
                } else {
                    $(this).addClass('expand')
                }
                softphone.spItems.map(item => {
                    if(item.show === 0) {
                        $('.'+ item.key).toggle();
                    }
                });
                if (!softphone.makeCallVisible) {
                    hideBtn($(BUTTONS.MAKE_CALL));
                }
                if (!softphone.releaseCallVisible) {
                    hideBtn($(BUTTONS.RELEASE));
                }
                if (!softphone.holdVisible) {
                    hideBtn($(BUTTONS.HOLD));
                }
                if (!softphone.initConferenceVisible) {
                    hideBtn($(BUTTONS.INIT_CONFERENCE));
                }
                if (!softphone.initTransferVisible) {
                    hideBtn($(BUTTONS.INIT_TRANSFER));
                }
                if (!softphone.reconnectVisible) {
                    hideBtn($(BUTTONS.RECONNECT));
                }
                if (!softphone.directTransferVisible) {
                    hideBtn($(BUTTONS.DIRECT_TRANSFER));
                }
                if (!softphone.notReadyVisible) {
                    hideBtn($(BUTTONS.NOT_READY));
                }
                if (!softphone.readyVisible) {
                    hideBtn($(BUTTONS.READY));
                }
                if (!softphone.breakVisible) {
                    hideBtn($(BUTTONS.BREAK));
                }
                if (!softphone.muteVisible) {
                    hideBtn($(BUTTONS.MUTE));
                }
                if (!softphone.nightRingVisible) {
                    hideBtn($(BUTTONS.NIGHT_RING_ON));
                }

                if (!softphone.initTransferQueueVisible) {
                    hideBtn($(BUTTONS.TRANSFER_TO_QUEUE));
                }
                if (!softphone.initTransferIVRVisible) {
                    hideBtn($(BUTTONS.TRANSFER_TO_IVR));
                }
            });

            $(BUTTONS.ANI).keypress(function (evt) {
                if (evt.keyCode === 13) {//回车拨打
                    if(softphone.makeCallVisible && softphone.makeCallEnabled) {
                        if (softphone.agentLogined) {
                            $(BUTTONS.MAKE_CALL).click();
                        }
                    }
                }
            }).click(function (e) {
                e.stopPropagation();
                $(BUTTONS.ANI_HIS).empty();
                var aniLi = '';
                $(softphone.aniQueue).each(function (i, num) {
                    aniLi += '<li>' + num + '</li>';
                });
                if (aniLi) {
                    $(aniLi).click(function () {
                        $(BUTTONS.ANI).val($(this).text());
                    }).appendTo($(BUTTONS.ANI_HIS));
                    showBtn($(BUTTONS.ANI_HIS));
                    $(window).one('click', function () {
                        hideBtn($(BUTTONS.ANI_HIS));
                    })
                }
            }).dblclick(function (evt) {
                $E.events.notify($CONST.SoftphoneEvent.NUMBER_INPUT_DOUBLE_CLICKED);
            });

            $(BUTTONS.NUM_KEYBOARD_SWITCHER).on('click', function () {
                if ($(BUTTONS.NUM_CONTAINER).is(':hidden')) {
                    showBtn($(BUTTONS.NUM_CONTAINER));
                    hideBtn($(BUTTONS.NUM_KEYBOARD_CONTAINER))
                } else {
                    hideBtn($(BUTTONS.NUM_CONTAINER));
                    showBtn($(BUTTONS.NUM_KEYBOARD_CONTAINER))
                }
            });

            $(BUTTONS.NUM_KEYBOARD).on('click', function () {
                if (softphone.agentLogined) {
                    let num = $(this).text();
                    softphone.sendDTMF(num);
                }
            });

            //初始化通话时长更新定时器
            softphone.callTimeTimer = Timer.create(1000, function () {
                var d = new Date(new Date().getTime() - softphone.baseStartTime);
                var hour = d.getHours() + d.getTimezoneOffset() / 60;
                var min = ("00" + d.getMinutes()).substr(-2);
                var sec = ("00" + d.getSeconds()).substr(-2);
                var displayTime;
                if (d || hour || min || sec) {
                    if (hour > 0) {
                        displayTime = "<span>" + (hour + ":" + min + ":" + sec) + "</span>";
                    } else {
                        displayTime = "<span>" + (min + ":" + sec) + "</span>"
                    }
                } else {
                    displayTime = "<span>--:--</span>"
                }
                $("#c_softphone .calltime").html(displayTime);
            });

            //初始化来电号码闪烁定时器
            softphone.callNumBlinkTimer = Timer.create(1000, function () {
                let callNumDom = $("#c_softphone .sp_callnum");
                if (!$F.isEmpty(callNumDom.html())) {
                    if (callNumDom.data("state") === 1) {
                        $("span", callNumDom).addClass('blink');
                        callNumDom.data("state", 0);
                    } else {
                        $("span", callNumDom).removeClass('blink');
                        callNumDom.data("state", 1);
                    }
                }
            });

            var STLAST = $F.parseInt(project.getParam("STLAST"));
            var STFSTR = project.getParam("STFSTR");
            if (STLAST === 1) {
                //init status relation
                data = project.commonQuerySync("Softphone.statusrelation.query", []);
                if (data && data.value[0].count > 0) {
                    for (let i = 0; i < data.value[0].count; i++) {
                        softphone.statusRelations[data.value[0].fields[i][0]] = {
                            ctistatus: data.value[0].fields[i][0],
                            relationstatus: data.value[0].fields[i][1],
                            overtime: data.value[0].fields[i][2],
                            statusdesc: data.value[0].fields[i][3],
                            timeoutcolor: data.value[0].fields[i][4]
                        };
                    }
                }
                //初始化状态持续时长定时器
                softphone.stateLastTimer = Timer.create(1000, function () {
                    var key = softphone.currentCTIStatus === CTIStatus.ACW ? 4 : softphone.currentCTIStatus;
                    var currentStatusRelation = softphone.statusRelations[key],
                        useColor = "", timeoutColor = "#FF0000", overtime = 0;
                    if (currentStatusRelation) {
                        overtime = parseInt(currentStatusRelation.overtime);
                        if ($F.isColorStr(currentStatusRelation.timeoutcolor)) {
                            if (currentStatusRelation.timeoutcolor.startsWith('#')) {
                                timeoutColor = currentStatusRelation.timeoutcolor;
                            } else {
                                timeoutColor = "#" + currentStatusRelation.timeoutcolor;
                            }
                        }
                    }
                    softphone.stateLastTime.setSeconds(softphone.stateLastTime.getSeconds() + 1);
                    //test
                    var formatString = STFSTR ? STFSTR : "mm:ss";
                    if (softphone.stateLastTime.getHours() > 0) {
                        formatString = "hh:mm:ss";
                    }
                    var stateLastStr = softphone.stateLastTime.format(formatString);
                    if (overtime > 0) {
                        var lastSeconds = softphone.stateLastTime.getHours() * 60 * 60 + softphone.stateLastTime.getMinutes() * 60 + softphone.stateLastTime.getSeconds();
                        if (lastSeconds > overtime) {
                            useColor = "style='color: " + timeoutColor + "'";
                        }
                    }
                    $("#c_softphone .sp_status_lasttime").html("<span " + useColor + ">" + stateLastStr + "</span>");
                });
                //$("#c_softphone .sp_status_lasttime").show();
                softphone.stateLastTimer.start();
                softphone.stateChange();
            } else if (STLAST === 2) {
                // 新版软电话状态提醒
                // SELECT CONFIG_GUID,CONFIG_DESC,ROLEGROUP_ID,STATUS,WORKMODE, REASONCODE, OVERTIME, TIMEOUTCOLOR FROM AGENTSTATEALERT_CONFIG WHERE ROLEGROUP_ID = @C1S OR ROLEGROUP_ID IS NULL;
                data = project.commonQuerySync("Softphone.agentstatealert_config.query", []);
                if (data && data.value[0].count > 0) {
                    for (let i = 0; i < data.value[0].count; i++) {
                        let status = data.value[0].fields[i][3],
                            workmode = data.value[0].fields[i][4],
                            reasoncode = data.value[0].fields[i][5] || '',
                            rolegroupId = data.value[0].fields[i][2];
                        let key;
                        if (status >= 20) {
                            key = status;
                        } else {
                            key = status + ':' + workmode + (reasoncode ? (':' + reasoncode) : '');
                        }
                        if (!softphone.agentStateAlert[key] || rolegroupId) { // 优先当前工作组
                            softphone.agentStateAlert[key] = {
                                status: status,
                                workmode: workmode,
                                reasoncode: reasoncode,
                                overtime: data.value[0].fields[i][6],
                                timeoutcolor: data.value[0].fields[i][7]
                            };
                        }
                    }
                }

                //初始化状态持续时长定时器
                softphone.stateLastTimer = Timer.create(1000, function () {
                    let key;
                    if (softphone.currentCTIStatus >= 20) {
                        key = softphone.currentCTIStatus;
                    } else {
                        // currentCTIStatus中的ACW和jeff定义的agent_current_state不匹配的，因此这里要判断一下，如果是ACW，则直接用3（ACW是通过3(agentstate)-4(agentmode)来判断的）
                        let agentCurrentState = softphone.currentCTIStatus === CTIStatus.ACW ? 3 : softphone.currentCTIStatus;
                        key = agentCurrentState + ':' + softphone.currentAgentMode + (softphone.currentReasonCode ? (':' + softphone.currentReasonCode) : '');
                    }
                    let currentAgentStateAlert = softphone.agentStateAlert[key],
                        useColor = "", timeoutColor = "#FF0000", overtime = 0;
                    if (currentAgentStateAlert) {
                        overtime = parseInt(currentAgentStateAlert.overtime);
                        if ($F.isColorStr(currentAgentStateAlert.timeoutcolor)) {
                            if (currentAgentStateAlert.timeoutcolor.startsWith('#')) {
                                timeoutColor = currentAgentStateAlert.timeoutcolor;
                            } else {
                                timeoutColor = "#" + currentAgentStateAlert.timeoutcolor;
                            }
                        }
                    }
                    softphone.stateLastTime.setSeconds(softphone.stateLastTime.getSeconds() + 1);
                    let formatString = STFSTR ? STFSTR : "mm:ss";
                    if (softphone.stateLastTime.getHours() > 0) {
                        formatString = "hh:mm:ss";
                    }
                    let stateLastStr = softphone.stateLastTime.format(formatString);
                    if (overtime > 0) {
                        let lastSeconds = softphone.stateLastTime.getHours() * 60 * 60 + softphone.stateLastTime.getMinutes() * 60 + softphone.stateLastTime.getSeconds();
                        if (lastSeconds > overtime) {
                            useColor = "style='color: " + timeoutColor + "'";
                        }
                    }
                    $("#c_softphone .sp_status_lasttime").html("<span " + useColor + ">" + stateLastStr + "</span>");
                });
                //$("#c_softphone .sp_status_lasttime").show();
                softphone.stateLastTimer.start();
                softphone.stateChange();
            } else {
                $("#c_softphone .sp_status_lasttime").hide();
            }

            //初始化应答按钮闪烁定时器
            softphone.answerBtnBlinkTimer = Timer.create(1000, function () {
                var answer = $("#c_softphone button.sp_answer");
                if (!answer.hasClass('sp_answer_blink')) {
                    answer.addClass('sp_answer_blink');
                } else {
                    answer.removeClass('sp_answer_blink');
                }
            });

            softphone.initialized = true;
            $E.events.notify(EVENTS.INITIALIZED);
            callback && callback();
        });
    };
    /**
     * 初始化
     * @param callback 初始化成功后的回调
     */
    Softphone.prototype.init = function (callback) {
        const softphone = this, project = softphone.getCurrentProject();
        let softphoneDom = '', attr = '';

        $.getJSON('js/softphone/config.json').done(function(data) {
            if (data && data.spItems) {
                softphone.spItems = data.spItems;
                softphone.spItems.forEach((item) => {
                    if(item.show === 0) {
                        attr = 'data-show="0" style="display: none"';
                    } else {
                        attr = '';
                    }

                    if(item.key === 'sp_answer')
                        softphoneDom += '<button class="sp_answer" title="' + $F.lang('softphoneEle.sp_answer') + '" '+ attr +'></button>';
                    if (item.key === 'sp_hangup')
                        softphoneDom += '<button class="sp_hangup" title="' + $F.lang('softphoneEle.sp_hungup') + '" '+ attr +'></button>';
                    if (item.key === 'sp_holding')
                        softphoneDom += '<button class="sp_holding" title="' + $F.lang('softphoneEle.sp_hold') + '" '+ attr +'></button>';
                    if (item.key === 'sp_retrieve')
                        softphoneDom += '<button class="sp_retrieve" title="' + $F.lang('softphoneEle.sp_holdcancel') + '" '+ attr +'></button>';
                    if (item.key === 'num_container')
                        softphoneDom += '<div class="sp_num_container" '+ attr +'>' +
                            '<form autocomplete="off" action="javascript:;">' +
                            '<input class="ani" type="text" placeholder="' + $F.lang('softphoneEle.sp_number') + '">' +
                            '</form>' +
                            '<ul class="ani_his"></ul>' +
                            '</div>';
                    if (item.key === 'keyboard_container')
                        softphoneDom += '<div class="num_keyboard_container" '+ attr +'>' +
                            '<button class="num_keyboard">1</button>' +
                            '<button class="num_keyboard">2</button>' +
                            '<button class="num_keyboard">3</button>' +
                            '<button class="num_keyboard">4</button>' +
                            '<button class="num_keyboard">5</button>' +
                            '<button class="num_keyboard">6</button>' +
                            '<br>' +
                            '<button class="num_keyboard">7</button>' +
                            '<button class="num_keyboard">8</button>' +
                            '<button class="num_keyboard">9</button>' +
                            '<button class="num_keyboard">*</button>' +
                            '<button class="num_keyboard">0</button>' +
                            '<button class="num_keyboard">#</button>' +
                            '</div>';
                    if (item.key === 'keyboard_switcher')
                        softphoneDom += '<button class="num_keyboard_switcher" '+ attr +'></button>';
                    if (item.key === 'sp_dailing')
                        softphoneDom += '<button class="sp_dailing" title="' + $F.lang('softphoneEle.sp_dial') + '" '+ attr +'></button>';
                    if (item.key === 'sp_init_transfer')
                        softphoneDom += '<button class="sp_init_transfer" title="' + $F.lang('softphoneEle.sp_transfer') + '" '+ attr +'></button>';
                    if (item.key === 'sp_complete_transfer')
                        softphoneDom += '<button class="sp_complete_transfer" title="' + $F.lang('softphoneEle.sp_transferComplete') + '" '+ attr +'></button>';
                    if (item.key === 'sp_direct_transfer')
                        softphoneDom += '<button class="sp_direct_transfer" title="' + $F.lang('softphoneEle.sp_transfer2') + '" '+ attr +'></button>';
                    if (item.key === 'sp_init_conference')
                        softphoneDom += '<button class="sp_init_conference" title="' + $F.lang('softphoneEle.sp_meeting') + '" '+ attr +'></button>';
                    if (item.key === 'sp_complete_conference')
                        softphoneDom += '<button class="sp_complete_conference" title="' + $F.lang('softphoneEle.sp_meetingComplete') + '" '+ attr +'></button>';
                    if (item.key === 'sp_reconnect')
                        softphoneDom += '<button class="sp_reconnect" title="' + $F.lang('softphoneEle.sp_transferBack') + '" '+ attr +'></button>';
                    if (item.key === 'sp_mute')
                        softphoneDom += '<button class="sp_mute" title="' + $F.lang('softphoneEle.sp_mute') + '" '+ attr +'></button>';
                    if (item.key === 'sp_unmute')
                        softphoneDom += '<button class="sp_unmute" title="' + $F.lang('softphoneEle.sp_muteCancel') + '" '+ attr +'></button>';
                    if (item.key === 'sp_night_ring_on')
                        softphoneDom += '<button class="sp_night_ring_on" title="' + $F.lang('softphoneEle.sp_nightRingOn') + '" '+ attr +'></button>';
                    if (item.key === 'sp_night_ring_off')
                        softphoneDom += '<button class="sp_night_ring_off" title="' + $F.lang('softphoneEle.sp_nightRingOff') + '" '+ attr +'></button>';
                    if (item.key === 'sp_transfer_to_ivr')
                        softphoneDom += '<button class="sp_transfer_to_ivr" title="' + $F.lang('softphoneEle.sp_transferIVR') + '" '+ attr +'></button>';
                    if (item.key === 'sp_transfer_to_queue')
                        softphoneDom += '<button class="sp_transfer_to_queue" title="' + $F.lang('softphoneEle.sp_transferQueue') + '" '+ attr +'></button>';
                    if (item.key === 'sp_ready')
                        softphoneDom += '<button class="sp_ready" title="' + $F.lang('softphoneEle.sp_ready') + '" '+ attr +'></button>';
                    if (item.key === 'sp_not_ready')
                        softphoneDom += '<button class="sp_not_ready" title="' + $F.lang('softphoneEle.sp_unready') + '" '+ attr +'></button>';
                    if (item.key === 'sp_break')
                        softphoneDom += '<button class="sp_break" title="' + $F.lang('softphoneEle.sp_break') + '" '+ attr +'></button>'
                    if(item.key === 'sp_breakType')
                        softphoneDom += '<span class="sp_breaktype" '+ attr +'>' +
                            '<span class="sp_breaktype_label"></span>' +
                            '<select class="sp_breaktype_select"></select>' +
                            '</span>';
                    if (item.key === 'sp_signin')
                        softphoneDom += '<button class="sp_signin" title="' + $F.lang('softphoneEle.sp_signin') + '" '+ attr +'></button>';
                    if (item.key === 'sp_signout')
                        softphoneDom += '<button class="sp_signout" title="' + $F.lang('softphoneEle.sp_signout') + '" '+ attr +'></button>';
                    if (item.key === 'arrow'){
                        var name = item.name ? item.name : 'chevron-right';
                        softphoneDom += '<button class="arrow far fa-' + name + '" '+ attr +'></button>';
                    }
                    if (item.key === 'status')
                        softphoneDom += '<span class="sp_status" '+ attr +'>' + $F.lang('softphoneEle.sp_status') + '</span>';
                    if (item.key === 'sp_videoAnswer')
                        softphoneDom += '<button class="sp_videoAnswer" title="' + $F.lang('softphoneEle.sp_videoStart') + '" '+ attr +'></button>';
                    if (item.key === 'sp_videoHangup')
                        softphoneDom += '<button class="sp_videoHangup" title="' + $F.lang('softphoneEle.sp_videoEnd') + '" '+ attr +'></button>';
                    if (item.key === 'status_lasttime')
                        softphoneDom += '<span class="sp_status_lasttime" '+ attr +'></span>';
                    if (item.key === 'sp_info')
                        softphoneDom += '<span class="sp_info" '+ attr +'>' +
                            '<span>' +
                            '<span class="extension"></span><span class="agent_id"></span>' +
                            '</span>' +
                            '<span class="calltime"></span>' +
                            '</span>';
                    if (item.key === 'sp_callnum')
                        softphoneDom += '<span class="sp_callnum" '+ attr +'></span>';
                    if (item.key === 'sp_info_1920')
                        softphoneDom += '<span class="sp_info_1920" '+ attr +'>' +
                            '<span class="sp_block">' +
                            '<span class="extension_name">' + $F.lang('softphoneEle.sp_extension') + ':</span><span class="extension"></span>' +
                            '</span>' +
                            '<span>' +
                            '<span class="agent_name">' + $F.lang('softphoneEle.sp_agentId') + ':</span><span class="agent_id"></span>' +
                            '</span>' +
                            '</span>';
                    if (item.key === 'sp_calltime')
                        softphoneDom += '<span class="sp_calltime" '+ attr +'>' +
                            '<span class="sp_block">' + $F.lang('softphoneEle.sp_callDuration') + '</span>' +
                            '<span class="calltime"><span>0:00:00</span></span>' +
                            '</span>';
                    if (item.key === 'sp_lasttime')
                        softphoneDom += '<span class="sp_lasttime" '+ attr +'>' +
                            '<span class="sp_block">' + $F.lang('softphoneEle.sp_statusDuration') + '</span>' +
                            '<span class="sp_status_lasttime"></span>' +
                            '</span>';
                    if (item.key === 'sp_call')
                        softphoneDom += '<span class="sp_call" '+ attr +'>' +
                            '<span class="sp_block">' + $F.lang('softphoneEle.sp_callNumber') + '</span>' +
                            '<span class="sp_callnum"><span>--- ---</span></span>' +
                            '</span>';
                    if (item.key === 'sp_stat')
                        softphoneDom += '<span class="sp_stat" '+ attr +'>' +
                            '<span class="sp_block"><span class="sp_title">IB：</span><span class="sp_stat_ib"></span></span>' +
                            '<span><span class="sp_title">OB：</span><span class="sp_stat_ob"></span></span>' +
                            '</span>';
                    if (item.key === 'sp_queue')
                        softphoneDom += '<span class="sp_queue" '+ attr +'>' +
                            '<span class="sp_block">' + $F.lang('softphoneEle.sp_queue') + '</span>' +
                            '<span class="sp_queue_id"></span>' +
                            '</span>';
                });
                $('#c_softphone').html(softphoneDom);
            }

            if (!softphone.available()) {
                $F.log("Softphone.init", "WebSocket not connected, init softphone failed.");
                setBtnEnable($(BUTTONS.LOGIN), false);
                setBtnEnable($(BUTTONS.MAKE_CALL), false);
                setBtnEnable($(BUTTONS.ANSWER), false);
                setBtnEnable($(BUTTONS.RELEASE), false);
                setBtnEnable($(BUTTONS.HOLD), false);
                setBtnEnable($(BUTTONS.RETRIEVE), false);
                setBtnEnable($(BUTTONS.INIT_CONFERENCE), false);
                setBtnEnable($(BUTTONS.INIT_TRANSFER), false);
                setBtnEnable($(BUTTONS.COMPLETE_CONFERENCE), false);
                setBtnEnable($(BUTTONS.COMPLETE_TRANSFER), false);
                setBtnEnable($(BUTTONS.DIRECT_TRANSFER), false);
                setBtnEnable($(BUTTONS.RECONNECT), false);
                setBtnEnable($(BUTTONS.READY), false);
                setBtnEnable($(BUTTONS.NOT_READY), false);
                setBtnEnable($(BUTTONS.BREAK), false);
                setBtnEnable($(BUTTONS.MUTE), false);
                setBtnEnable($(BUTTONS.NIGHT_RING_ON), false);
                setBtnEnable($(BUTTONS.VIDEO_ANSWER), false);
                setBtnEnable($(BUTTONS.VIDEO_RELEASE), false);
                setBtnEnable($(BUTTONS.TRANSFER_TO_IVR), false);
                setBtnEnable($(BUTTONS.TRANSFER_TO_QUEUE), false);
                return;
            }

            //先弹出对话框获取ctiType，然后把ctiType传递到initSoftphone方法中去, 查询出数据时候就选，查不出就不选
            const ret = project.commonQuerySync("softphone.ctitype.query", []), ctiTypes = [];
            if (ret && ret.value[0].count > 0) {
                const retArr = $F.makeJsonArray(ret.value[0]);
                if (retArr.length === 1) {// 如果只查询出一个就直接按这个来初始化
                    doInitSoftphone(softphone, project, {
                        ctiType: retArr[0].CTI_ID
                    }, callback);
                } else {
                    retArr.forEach(function (cti) {
                        ctiTypes.push({
                            label: cti.CTI_DESC,
                            value: cti.CTI_ID
                        });
                    });

                    const dialog = $('<div class="sp_ctitype_dialog">');
                    dialog.append('<div><span style="display:inline-block">' + $F.lang('softphone.cti') + ':</span><div class="sp_cti_type"></div></div>');
                    const ctiTypeCombox = $(".sp_cti_type", dialog).wisCombox({
                        tip: $F.lang('softphone.ctiSelect'),
                        maxHeight: 200
                    });
                    ctiTypeCombox.setData(ctiTypes);

                    if (!softphone.ctiTypeDialog) {
                        softphone.ctiTypeDialog = $F.createDialog(dialog, {
                            title: $F.lang('softphone.ctiSelect'),
                            closable: false,
                            onSubmit: function () {
                                var ctiType = $('.sp_ctitype_dialog .sp_cti_type').data('wisCombox').val();
                                if (ctiType) {
                                    $F.dialogClose(softphone.ctiTypeDialog);
                                    doInitSoftphone(softphone, project, {
                                        ctiType: ctiType.value
                                    }, callback);
                                } else {
                                    $F.alert($F.lang('softphone.ctiSelectAlert'));
                                }

                            }
                        });
                    } else {
                        Helper.masker.show(softphone.ctiTypeDialog);
                    }
                }
            } else {
                doInitSoftphone(softphone, project, callback);
            }
        });
    };

    Softphone.prototype.callSoftphoneLoginInfo = function (proj) {
        const softphone = this;
        const useLoginName = proj.getParam("LOGNAM") === "Y" ? 1 : 0;
        const loginInfo = "agent_id=" + $E.staff.agentId + "|loginname=" + $E.staff.loginName
            + "|staff_id=" + $E.staff.id + "|staffname=" + $E.staff.name
            + "|rolegroup_id=" + proj.groupId + "|project_id=" + proj.id
            + "|extension=" + $F.parseEmpty($E.staff.bean ? $E.staff.bean.EXTENSION : '') + "|useloginname=" + useLoginName
            + "|token=" + proj.token + "|epid=" + $E.staff.epid + "|CampaignID=*|dbMasker=" + proj.isDbMask() + "|ngsurl=" + $E.host + $E.url;
        $F.log("Softpohone.callSoftphoneLoginInfo", "Tell softphone logininfo", loginInfo);
        softphone.simpleCommonCall("logininfo", loginInfo, function (callResult) {
            $F.log("Softpohone.callSoftphoneLoginInfo", "CommonCall logininfo result", callResult);
            softphone.simpleCommonCall("QueryExtra", "CallName=SetPDSInfo|RunMode=1");
            $F.log("Softpohone.callSoftphoneLoginInfo", "Softphone CommonCall:QueryExtra,CallName=SetPDSInfo|RunMode=1");
        });//changeproject
    };

    Softphone.prototype.setJSService = function (proj) {
        let serviceUrl = $E.dataService.url;
        const SPPROX = proj.getParam('SPPROX');
        if ($E.dataService.api || SPPROX === '1') {
            //通过ngs代理来连
            serviceUrl = location.origin + $E.url + '/proxy?method=';
        } else {
            if (serviceUrl && !serviceUrl.startWith("http")) {
                serviceUrl = location.origin + serviceUrl;
            }
        }
        let setupStr = '(Server=(ServerHost=' + serviceUrl + ')(ServerPort=8080)(PoolName=)(token=' + proj.token + ')(dsKey=' + $E.dataService.key + ')(digest=' + proj.digest + ')(xhrDigest=' + $E.xhrDigest + '))';
        this.simpleCommonCall('setaps', setupStr);
    };

    /**
     * 获取当前项目，考虑到单独使用软电话时候，没有$E，没有project
     * @returns {undefined|*|Softphone.getCurrentProject|{getParam: project.getParam, commonQuerySync: project.commonQuerySync}}
     */
    Softphone.prototype.getCurrentProject = function () {
        if (!this.currentProject) {
            if (typeof ($E) !== 'undefined' && $.isFunction($E.getActiveProject)) {
                this.currentProject = $E.getActiveProject();
            } else {
                this.currentProject = {
                    getParam: function () {
                        return null;
                    },
                    commonQuerySync: function () {
                        return null;
                    }
                }
            }
        }
        return this.currentProject;
    };

    /**
     * 添加主叫号码到号码队列，用于之后的显示
     * @param num
     */
    Softphone.prototype.putToAniQueue = function (num) {
        var index = this.aniQueue.indexOf(num);
        if (index > -1) {
            this.aniQueue.splice(index, 1);
        } else {
            if (this.aniQueue.length >= this.aniQueueLength) {
                this.aniQueue.splice(this.aniQueueLength - 1, (this.aniQueue.length - this.aniQueueLength + 1));
            }
        }
        this.aniQueue.splice(0, 0, num);
    };

    /**
     * 根据当前callState和agentState 设置当前按钮状态
     */
        //setBtnShow用于展示所有button,便于setBtnStatus中逐个隐藏
    var setBtnShowAll = function () {
            showBtn($(BUTTONS.MAKE_CALL));
            showBtn($(BUTTONS.RECONNECT));
            showBtn($(BUTTONS.NUM_KEYBOARD_SWITCHER));
            showBtn($(BUTTONS.HOLD));
            showBtn($(BUTTONS.DIRECT_TRANSFER));
            showBtn($(BUTTONS.INIT_TRANSFER));
            showBtn($(BUTTONS.NUM_KEYBOARD));
            showBtn($(BUTTONS.READY));
            $(BUTTONS.NOT_READY).hide();
            showBtn($(BUTTONS.BREAK));
            showBtn($(BUTTONS.BREAK_TYPE));
            setBtnEnable($(BUTTONS.EXPANDS),true);
        }

    var setBtnVisiblity = function () {
        if (softphone.makeCallVisiblein === true) {
            hideBtn($(BUTTONS.MAKE_CALL));
        } else if (softphone.makeCallVisiblein === false) {
            showBtn($(BUTTONS.MAKE_CALL));
        }
        if (softphone.holdVisiblein === true) {
            hideBtn($(BUTTONS.HOLD));
        } else if (softphone.holdVisiblein === false) {
            showBtn($(BUTTONS.HOLD));
        }
        if (softphone.retrieveVisiblein === true) {
            hideBtn($(BUTTONS.RETRIEVE));
        } else if (softphone.retrieveVisiblein === false) {
            showBtn($(BUTTONS.RETRIEVE));
        }
        if (softphone.initConferenceVisiblein === true) {
            hideBtn($(BUTTONS.INIT_CONFERENCE));
        } else if (softphone.initConferenceVisiblein === false) {
            showBtn($(BUTTONS.INIT_CONFERENCE));
        }
        if (softphone.completeConferenceVisiblein === true) {
            hideBtn($(BUTTONS.COMPLETE_CONFERENCE));
        } else if (softphone.completeConferenceVisiblein === false) {
            showBtn($(BUTTONS.COMPLETE_CONFERENCE));
        }
        if (softphone.initTransferVisiblein === true) {
            hideBtn($(BUTTONS.INIT_TRANSFER));
        } else if (softphone.initTransferVisiblein === false) {
            showBtn($(BUTTONS.INIT_TRANSFER));
        }
        if (softphone.completeTransferVisiblein === true) {
            hideBtn($(BUTTONS.COMPLETE_TRANSFER));
        } else if (softphone.completeTransferVisiblein === false) {
            showBtn($(BUTTONS.COMPLETE_TRANSFER));
        }
        if (softphone.reconnectVisiblein === true) {
            hideBtn($(BUTTONS.RECONNECT));
        } else if (softphone.reconnectVisiblein === false) {
            showBtn($(BUTTONS.RECONNECT));
        }
        if (softphone.directTransferVisiblein === true) {
            hideBtn($(BUTTONS.DIRECT_TRANSFER));
        } else if (softphone.directTransferVisiblein === false) {
            showBtn($(BUTTONS.DIRECT_TRANSFER));
        }
        if (softphone.notReadyVisiblein === true) {
            hideBtn($(BUTTONS.NOT_READY));
        } else if (softphone.notReadyVisiblein === false) {
            showBtn($(BUTTONS.NOT_READY));
        }
        if (softphone.readyVisiblein === true) {
            hideBtn($(BUTTONS.READY));
        } else if (softphone.readyVisiblein === false) {
            showBtn($(BUTTONS.READY));
        }
        if (softphone.breakVisiblein === true) {
            hideBtn($(BUTTONS.BREAK));
        } else if (softphone.breakVisiblein === false) {
            showBtn($(BUTTONS.BREAK));
        }
        if (softphone.muteVisiblein === true) {
            hideBtn($(BUTTONS.MUTE));
        } else if (softphone.muteVisiblein === false) {
            showBtn($(BUTTONS.MUTE));
        }
        if (softphone.unmuteVisiblein === true) {
            hideBtn($(BUTTONS.UNMUTE));
        } else if (softphone.unmuteVisiblein === false) {
            showBtn($(BUTTONS.UNMUTE));
        }
        if (softphone.nightRingOnVisiblein === true) {
            hideBtn($(BUTTONS.NIGHT_RING_ON));
        } else if (softphone.nightRingOnVisiblein === false) {
            showBtn($(BUTTONS.NIGHT_RING_ON));
        }
        if (softphone.nightRingOffVisiblein === true) {
            hideBtn($(BUTTONS.NIGHT_RING_OFF));
        } else if (softphone.nightRingOffVisiblein === false) {
            showBtn($(BUTTONS.NIGHT_RING_OFF));
        }
        if (softphone.loginVisiblein === true) {
            hideBtn($(BUTTONS.LOGIN));
        } else if (softphone.loginVisiblein === false) {
            showBtn($(BUTTONS.LOGIN));
        }
        if (softphone.logoutVisiblein === true) {
            hideBtn($(BUTTONS.LOGOUT));
        } else if (softphone.logoutVisiblein === false) {
            showBtn($(BUTTONS.LOGOUT));
        }
        if (softphone.numContainerVisiblein === true) {
            hideBtn($(BUTTONS.NUM_KEYBOARD_CONTAINER));
        } else if (softphone.numContainerVisiblein === false) {
            showBtn($(BUTTONS.NUM_KEYBOARD_CONTAINER));
        }
        if (softphone.transferToIvrVisiblein === true) {
            hideBtn($(BUTTONS.TRANSFER_TO_IVR));
        } else if (softphone.transferToIvrVisiblein === false) {
            showBtn($(BUTTONS.TRANSFER_TO_IVR));
        }
        if (softphone.transferToQueueVisiblein === true) {
            hideBtn($(BUTTONS.TRANSFER_TO_QUEUE));
        } else if (softphone.transferToQueueVisiblein === false) {
            showBtn($(BUTTONS.TRANSFER_TO_QUEUE));
        }
        if (softphone.expandsVisiblein === true) {
            setBtnEnable($(BUTTONS.EXPANDS),false);
        } else if (softphone.expandsVisiblein === false) {
            showBtn($(BUTTONS.EXPANDS));
        }
        if (softphone.numKeyboardSwitcherVisiblein === true) {
            hideBtn($(BUTTONS.NUM_KEYBOARD_SWITCHER));
        } else if (softphone.numKeyboardSwitcherVisiblein === false) {
            showBtn($(BUTTONS.NUM_KEYBOARD_SWITCHER));
        }
        if (softphone.breakTypeSelectVisiblein === true) {
            hideBtn($(BUTTONS.BREAK_TYPE));
        } else if (softphone.breakTypeSelectVisiblein === false) {
            showBtn($(BUTTONS.BREAK_TYPE));
        }
        if (softphone.answerVisiblein === true) {
            hideBtn($(BUTTONS.ANSWER));
        } else if (softphone.answerVisiblein === false) {
            showBtn($(BUTTONS.ANSWER));
        }
        if (softphone.videoAnswerVisiblein === true) {
            hideBtn($(BUTTONS.VIDEO_ANSWER));
        } else if (softphone.videoAnswerVisiblein === false) {
            showBtn($(BUTTONS.VIDEO_ANSWER));
        }
    }

    Softphone.prototype.setBtnStatus = function () {
        const softphone = this;
        setBtnShowAll();
        if (softphone.agentLogined) {
            hideBtn($(BUTTONS.LOGIN));
            showBtn($(BUTTONS.LOGOUT));
            // $(BUTTONS.BREAK_TYPE_SELECT).attr("disabled", false);
            if (softphone.currentCallState === CallState.ECT_UNKNOWN) {
                if (softphone.makeCallEnabled) {
                    setBtnEnable($(BUTTONS.MAKE_CALL), true);
                }
                hideBtn($(BUTTONS.ANSWER));
                showBtn($(BUTTONS.RELEASE));

                setBtnEnable($(BUTTONS.ANSWER), false);
                setBtnEnable($(BUTTONS.RELEASE), false);
                setBtnEnable($(BUTTONS.HOLD), false);
                setBtnEnable($(BUTTONS.RETRIEVE), false);
                setBtnEnable($(BUTTONS.INIT_CONFERENCE), false);
                setBtnEnable($(BUTTONS.INIT_TRANSFER), false);
                setBtnEnable($(BUTTONS.COMPLETE_CONFERENCE), false);
                setBtnEnable($(BUTTONS.COMPLETE_TRANSFER), false);
                setBtnEnable($(BUTTONS.DIRECT_TRANSFER), false);
                setBtnEnable($(BUTTONS.RECONNECT), false);
                setBtnEnable($(BUTTONS.READY), false);
                setBtnEnable($(BUTTONS.NOT_READY), false);
                setBtnEnable($(BUTTONS.BREAK), false);
                setBtnEnable($(BUTTONS.MUTE), false);
                setBtnEnable($(BUTTONS.TRANSFER_TO_IVR), false);
                setBtnEnable($(BUTTONS.TRANSFER_TO_QUEUE), false);
                if (softphone.nightRingEnabled) {
                    setBtnEnable($(BUTTONS.NIGHT_RING_ON), true);
                }

                showBtn($(BUTTONS.LOGOUT));
            } else {
                setBtnEnable($(BUTTONS.MAKE_CALL), false);
            }

            if (softphone.currentCallState === CallState.ECT_RINGING) {
                showBtn($(BUTTONS.ANSWER));
                hideBtn($(BUTTONS.RELEASE));
                setBtnEnable($(BUTTONS.ANSWER), true);
                $('.sp_call .sp_block').html($F.lang('softphoneEle.sp_callNumber'));
            } else if (softphone.currentCallState === CallState.ECT_DIALING) {
                hideBtn($(BUTTONS.ANSWER));
                showBtn($(BUTTONS.RELEASE));
                if (softphone.releaseCallEnabled) {
                    setBtnEnable($(BUTTONS.RELEASE), true);
                }
            } else if (softphone.currentCallState === CallState.ECT_TALKING) {
                hideBtn($(BUTTONS.ANSWER));
                showBtn($(BUTTONS.RELEASE));
                hideBtn($(BUTTONS.RETRIEVE));
                showBtn($(BUTTONS.HOLD));
                hideBtn($(BUTTONS.COMPLETE_CONFERENCE));
                showBtn($(BUTTONS.INIT_CONFERENCE));
                showBtn($(BUTTONS.INIT_TRANSFER));

                softphone.initTransferIVRVisible && showBtn($(BUTTONS.TRANSFER_TO_IVR));
                softphone.initTransferQueueVisible && showBtn($(BUTTONS.TRANSFER_TO_QUEUE));
                showBtn($(BUTTONS.DIRECT_TRANSFER));

                hideBtn($(BUTTONS.COMPLETE_TRANSFER));
                //改
                if (softphone.releaseCallEnabled) {
                    setBtnEnable($(BUTTONS.RELEASE), true);
                }
                if (softphone.holdEnabled) {
                    setBtnEnable($(BUTTONS.HOLD), true);
                }
                if (softphone.initConferenceEnabled) {
                    setBtnEnable($(BUTTONS.INIT_CONFERENCE), true);
                }
                if (softphone.initTransferEnabled) {
                    setBtnEnable($(BUTTONS.INIT_TRANSFER), true);
                }
                if (softphone.directTransferEnabled) {
                    setBtnEnable($(BUTTONS.DIRECT_TRANSFER), true);
                }
                if (softphone.muteEnabled) {
                    setBtnEnable($(BUTTONS.MUTE), true);
                }

                if (softphone.initTransferQueueEnabled) {
                    setBtnEnable($(BUTTONS.TRANSFER_TO_QUEUE), true);
                }
                if (softphone.initTransferIVREnabled) {
                    setBtnEnable($(BUTTONS.TRANSFER_TO_IVR), true);
                }

                showBtn($(BUTTONS.TRANSFER_TO_IVR));

                if (softphone.mediaType === 'video') {
                    setBtnVisiblity();
                }


            } else if (softphone.currentCallState === CallState.ECT_HOLD) {
                showBtn($(BUTTONS.RETRIEVE));
                hideBtn($(BUTTONS.HOLD));

                setBtnEnable($(BUTTONS.RELEASE), false);
                setBtnEnable($(BUTTONS.INIT_CONFERENCE), false);
                setBtnEnable($(BUTTONS.INIT_TRANSFER), false);
                setBtnEnable($(BUTTONS.COMPLETE_CONFERENCE), false);
                setBtnEnable($(BUTTONS.COMPLETE_TRANSFER), false);
                setBtnEnable($(BUTTONS.DIRECT_TRANSFER), false);
                setBtnEnable($(BUTTONS.RECONNECT), false);
                setBtnEnable($(BUTTONS.TRANSFER_TO_IVR), false);
                setBtnEnable($(BUTTONS.TRANSFER_TO_QUEUE), false);

                setBtnEnable($(BUTTONS.RETRIEVE), true);
            }
            if (softphone.currentCallState === CallState.ECT_TALKINGHOLD || softphone.currentCallState === (softphone.transferOnDialingHold ? CallState.ECT_DIALINGHOLD : -1)) {
                if (softphone.agentConferenced) {
                    hideBtn($(BUTTONS.INIT_CONFERENCE));
                    showBtn($(BUTTONS.COMPLETE_CONFERENCE));
                    setBtnEnable($(BUTTONS.COMPLETE_CONFERENCE), true);
                } else if (softphone.agentTransfered) {
                    hideBtn($(BUTTONS.INIT_TRANSFER));
                    showBtn($(BUTTONS.COMPLETE_TRANSFER));
                    setBtnEnable($(BUTTONS.COMPLETE_TRANSFER), true);
                }
            }
            if (softphone.currentCallState === CallState.ECT_TALKINGHOLD || softphone.currentCallState === CallState.ECT_DIALINGHOLD) {
                hideBtn($(BUTTONS.RETRIEVE));
                showBtn($(BUTTONS.HOLD));
                setBtnEnable($(BUTTONS.HOLD), false);
                setBtnEnable($(BUTTONS.RETRIEVE), false);
                if (softphone.reconnectEnabled) {
                    setBtnEnable($(BUTTONS.RECONNECT), true);
                }
            } else {
                setBtnEnable($(BUTTONS.RECONNECT), false);
            }

            if (softphone.currentAgentState === AgentState.EAS_READY) {
                if (softphone.notReadyEnabled) {
                    setBtnEnable($(BUTTONS.NOT_READY), true);
                }
                showBtn($(BUTTONS.NOT_READY));

                hideBtn($(BUTTONS.READY));
            } else if (softphone.currentAgentState === AgentState.EAS_NOTREADY) {
                if (softphone.readyEnabled) {
                    setBtnEnable($(BUTTONS.READY), true);
                }
                if (softphone.readyVisiblein === true) {
                } else {
                    showBtn($(BUTTONS.READY));
                }
                hideBtn($(BUTTONS.NOT_READY));
                // $(BUTTONS.BREAK_TYPE_SELECT).attr("disabled", true);
            }

            $(BUTTONS.BREAK).removeClass("request");
            if (softphone.breakEnabled) {
                setBtnEnable($(BUTTONS.BREAK), true);
            }
            $(BUTTONS.BREAK_TYPE_SELECT).attr("disabled", false);
            $('#pizza_kind').prop('disabled', false);
        } else {
            showBtn($(BUTTONS.LOGIN));
            hideBtn($(BUTTONS.LOGOUT));

            if (!softphone.makeCallVisible) {
                hideBtn($(BUTTONS.MAKE_CALL));
            }
            if (!softphone.releaseCallVisible) {
                hideBtn($(BUTTONS.RELEASE));
            }
            if (!softphone.holdVisible) {
                hideBtn($(BUTTONS.HOLD));
            }
            if (!softphone.initConferenceVisible) {
                hideBtn($(BUTTONS.INIT_CONFERENCE));
            }
            if (!softphone.initTransferVisible) {
                hideBtn($(BUTTONS.INIT_TRANSFER));
            }
            if (!softphone.reconnectVisible) {
                hideBtn($(BUTTONS.RECONNECT));
            }
            if (!softphone.directTransferVisible) {
                hideBtn($(BUTTONS.DIRECT_TRANSFER));
            }
            if (!softphone.notReadyVisible) {
                hideBtn($(BUTTONS.NOT_READY));
            }
            if (!softphone.readyVisible) {
                hideBtn($(BUTTONS.READY));
            }
            if (!softphone.breakVisible) {
                hideBtn($(BUTTONS.BREAK));
            }
            if (!softphone.muteVisible) {
                hideBtn($(BUTTONS.MUTE));
            }
            if (!softphone.nightRingVisible) {
                hideBtn($(BUTTONS.NIGHT_RING_ON));
            }
            if (!softphone.initTransferQueueVisible) {
                hideBtn($(BUTTONS.TRANSFER_TO_QUEUE));
            }
            if (!softphone.initTransferIVRVisible) {
                hideBtn($(BUTTONS.TRANSFER_TO_IVR));
            }

            setBtnEnable($(BUTTONS.ANSWER), false);
            setBtnEnable($(BUTTONS.RELEASE), false);
            setBtnEnable($(BUTTONS.HOLD), false);
            setBtnEnable($(BUTTONS.RETRIEVE), false);
            setBtnEnable($(BUTTONS.INIT_CONFERENCE), false);
            setBtnEnable($(BUTTONS.INIT_TRANSFER), false);
            setBtnEnable($(BUTTONS.COMPLETE_CONFERENCE), false);
            setBtnEnable($(BUTTONS.COMPLETE_TRANSFER), false);
            setBtnEnable($(BUTTONS.DIRECT_TRANSFER), false);
            setBtnEnable($(BUTTONS.RECONNECT), false);
            setBtnEnable($(BUTTONS.MAKE_CALL), false);
            setBtnEnable($(BUTTONS.READY), false);
            setBtnEnable($(BUTTONS.NOT_READY), false);
            setBtnEnable($(BUTTONS.BREAK), false);
            setBtnEnable($(BUTTONS.MUTE), false);
            setBtnEnable($(BUTTONS.NIGHT_RING_ON), false);
            setBtnEnable($(BUTTONS.TRANSFER_TO_IVR), false);
            setBtnEnable($(BUTTONS.TRANSFER_TO_QUEUE), false);

            $(BUTTONS.BREAK_TYPE_SELECT).attr("disabled", "disabled");
        }
    };

    /**
     * 根据agentState和callState设置当前状态
     */
    Softphone.prototype.setStatusByAgentStateAndCallState = function () {
        softphone.setBreakTypeLabelText("");
        if (softphone.currentCallState === CallState.ECT_DIALING || softphone.currentCallState === CallState.ECT_RINGING
            || softphone.currentCallState === CallState.ECT_TALKING || softphone.currentCallState === CallState.ECT_HOLD
            || softphone.currentCallState === CallState.ECT_DIALINGHOLD || softphone.currentCallState === CallState.ECT_TALKINGHOLD) {
            if (softphone.currentCallState === CallState.ECT_RINGING) {
                softphone.currentAgentStateText = "<span class='ringing'>" + $F.lang('softphone.ringing') + "</span>";
                softphone.currentCTIStatus = CTIStatus.RINGING;
            } else if (softphone.currentCallState === CallState.ECT_HOLD) {
                softphone.currentAgentStateText = "<span class='hold'>" + $F.lang('softphone.hold') + "</span>";
                softphone.currentCTIStatus = CTIStatus.HOLD;
            } else if (softphone.currentCallState === CallState.ECT_DIALING) {
                softphone.currentAgentStateText = "<span class='dialing'>" + $F.lang('softphone.dialing') + "</span>";
                softphone.currentCTIStatus = CTIStatus.DIALING;
            } else if (softphone.currentCallState === CallState.ECT_DIALINGHOLD) {
                softphone.currentAgentStateText = "<span class='dialing'>" + $F.lang('softphone.dialing') + "</span>";
                softphone.currentCTIStatus = CTIStatus.HOLDDIALING;
            } else if (softphone.currentCallState === CallState.ECT_TALKINGHOLD) {
                softphone.currentAgentStateText = "<span class='connect'>" + $F.lang('softphone.connect') + "</span>";
                softphone.currentCTIStatus = CTIStatus.HOLDTALKING;
            } else { // ECT_TALKING
                if (softphone.currentCallInfo.callParty && softphone.currentCallInfo.callParty.activeParties > 2) {
                    softphone.currentAgentStateText = "<span class='call_duration'>" + $F.lang('softphone.consulting') + "</span>";
                } else {
                    softphone.currentAgentStateText = "<span class='call_duration'>" + $F.lang('softphone.callDuration') + "</span>";
                }
                softphone.currentCTIStatus = CTIStatus.BUSY;
            }
            if (softphone.currentCallState !== CallState.ECT_TALKING) {
                softphone.isMute = false;
            }
        } else {
            if (softphone.currentAgentState === AgentState.EAS_NOTREADY) {
                if (softphone.currentAgentMode === AgentMode.EAM_ACW) {
                    softphone.currentAgentStateText = "<span class='acw'>" + $F.lang('softphone.acw') + "</span>";
                    softphone.currentCTIStatus = CTIStatus.ACW;
                } else if (softphone.currentAgentMode === AgentMode.EAM_PREOCCUPIED) {
                    softphone.currentAgentStateText = "<span class='pre_occupied'>" + $F.lang('softphone.preOccupied') + "</span>";
                    softphone.currentCTIStatus = CTIStatus.AUX;
                } else {
                    softphone.currentAgentStateText = "<span class='not_ready'>" + $F.lang('softphone.notReady') + "</span>";
                    softphone.currentCTIStatus = CTIStatus.AUX;
                }
            } else if (softphone.currentAgentState === AgentState.EAS_READY) {
                softphone.currentAgentStateText = "<span class='ready'>" + $F.lang('softphone.ready') + "</span>";
                softphone.currentCTIStatus = CTIStatus.READY;
                if (softphone.saveAuxDetail) {// 如果开启保存auxdetail的话，准备好的时候要去记录aux的结束时间
                    if (softphone.auxDetail.guid && softphone.auxDetail.saved) {
                        var project = softphone.getCurrentProject();
                        project.commonUpdateSync('Softphone.auxdetail.update', [softphone.auxDetail.guid]);
                        softphone.auxDetail = {};
                    }
                }
            } else if (softphone.currentAgentState === AgentState.EAS_LOGOUT) {
                softphone.currentAgentStateText = "";
            }
        }
        $F.log("Softphone.setStatusByAgentStateAndCallState", "Set current agent state text: " + softphone.currentAgentStateText);
    };

    /**
     * 根据当前状态设置坐席状态label显示
     */
    Softphone.prototype.setAgentStateText = function () {
        this.setStatusByAgentStateAndCallState();
        this.updateAgentStateText(this.currentAgentStateText);
    };


    Softphone.prototype.updateAgentStateText = function (agentStateText) {
        if ($("#c_softphone .sp_status span").html() !== $(agentStateText).html()) {
            $("#c_softphone .sp_status").html(agentStateText);
            this.stateChange();
        }
    };

    /**
     * 初始化状态持续时长
     */
    Softphone.prototype.initStateLastTime = function () {
        this.stateLastTime.setHours(0);
        this.stateLastTime.setMinutes(0);
        this.stateLastTime.setSeconds(0);
    };

    /**
     * 软电话状态改变
     */
    Softphone.prototype.stateChange = function () {
        this.initStateLastTime();
        this.getCurrentProject().events.notify(EVENTS.STATE_CHANGE_EVT, {
            stateText: this.currentAgentStateText,
            callState: this.currentCallState,
            agentState: this.currentAgentState,
            agentMode: this.currentAgentMode,
            reasonCode: this.currentReasonCode
        });
    };

    /**
     * 设置坐席是否登录
     * @param value (true|false)
     */
    Softphone.prototype.setAgentLogined = function (value) {
        if (this.agentLogined !== value) {
            this.agentLogined = value;
            $E.events.notify(EVENTS.SOFTPHONE_AGENT_LOGINED, value);
        }
    };

    /**
     * 刷新当前软电话统计状态
     * @param callStat
     */
    Softphone.prototype.refreshCallStat = function (callStat) {
        const softphone = this;
        if (!$F.isNull(callStat)) {
            softphone.totalIB = callStat.TotalIB;
            softphone.totalOB = callStat.TotalOB;
            softphone.totalIBAnswered = callStat.TotalIBAnswered;
            softphone.totalOBReached = callStat.TotalOBReached;
            softphone.totalIBDuration = callStat.TotalIBDuration;
            softphone.totalOBDuration = callStat.TotalOBDuration;
            softphone.totalIBDisplay = (softphone.totalIBAnswered || '0') + "(" + (softphone.totalIBDuration || '0') + ")";
            softphone.totalOBDisplay = (softphone.totalOBReached || '0') + "(" + (softphone.totalOBDuration || '0') + ")";
        }

        $("#c_softphone .sp_stat .sp_stat_ib").html(softphone.totalIBDisplay);
        $("#c_softphone .sp_stat .sp_stat_ob").html(softphone.totalOBDisplay);
    };

    /**
     * 显示PDS市场活动选择对话框
     */
    Softphone.prototype.showPDSLoginDialog = function () {
        var softphone = this, proj = softphone.getCurrentProject(), PDSENA = proj.getParam('PDSENA');
        if (PDSENA > 0) {
            var closable = (PDSENA != 2);
            if (!softphone.pdsDialog) {
                var dialog = $('<div class="sp_psd_dialog">' +
                    '<select class="sp_pds_campagin">' +
                    '</div>');

                var ret = proj.commonQuerySync('PDS.Campaign.query', []);
                if (ret && ret.value[0].count > 0) {
                    var campaignList = $F.makeJsonArray(ret.value[0]);
                    $.each(campaignList, function (i, campaign) {
                        $('.sp_pds_campagin', dialog).append('<option value="' + campaign.CAMPAIGN_ID + '" cti-skill="' + campaign.CTISKILL + '">' + campaign.CAMPAIGN_DESC + '</option>');
                    });
                }
                softphone.pdsDialog = $F.createDialog(dialog, {
                    title: $F.lang('softphone.pdsCampaignSelect'),
                    closable: closable,
                    onSubmit: function () {
                        if (softphone.available()) {
                            var selectedOption = $('.sp_pds_campagin', dialog).find("option:selected");
                            softphone.simpleCommonCall('QueryExtra', 'CallName=SetPDSInfo|CampaignID=' + selectedOption.val() + '|CTISkill=' + selectedOption.attr('cti-skill'));
                        } else {
                            $F.log('softphone - showPDSLoginDialog', 'WebSocket is not opened.');
                        }
                        $F.dialogClose(softphone.pdsDialog);
                    }
                });
            } else {
                Helper.masker.show(softphone.pdsDialog);
            }
        }
    };

    Softphone.prototype.showQueueSelectDialog = function () {
        var softphone = this, proj = softphone.getCurrentProject(), queues = [];
        var dialog = $('<div class="sp_queue_select_dialog"></div>');

        softphone.simpleCommonCall('getagentqueues', softphone.agentId, function (retArr) {
            if (retArr && retArr.length > 0) {
                retArr.forEach(function (q) {
                    queues.push({
                        label: q.QUEUENAME,
                        value: q.QUEUENUM
                    });
                });
            }

            var queueDom = '<div style="display: ' + (softphone.iniInfo.NeedQueue === 0 ? 'none' : 'block') + ';"><span style="display:inline-block">' + $F.lang('softphone.queue') + ':</span>';
            queueDom += '<div class="sp_queue_select" style="width: 168px;margin-left: 3px;margin-top: 5px;margin-bottom: 3px;"></div></div>';
            queueDom = $(queueDom);
            var queueCombox = $(".sp_queue_select", queueDom).wisCombox({
                tip: $F.lang('softphone.queueSelect'),
                maxHeight: 200,
                multi: !!softphone.iniInfo.QueueMultiSelect
            });
            queueCombox.setData(queues);

            dialog.append(queueDom);


            softphone.queueSelectDialog = $F.createDialog(dialog, {
                title: $F.lang('softphone.queueSelect'),
                closable: false,
                onSubmit: function () {
                    var selectQueues = $(".sp_queue_select", dialog).data('wisCombox').val(),
                        queues = [], queuesDesc, queue;
                    if (selectQueues && selectQueues.length > 0) {
                        selectQueues.forEach(function (q) {
                            queues.push(q.value);
                            queuesDesc.push(q.label);
                        });
                        queue = queues.join(';');
                        softphone.queueDesc = queuesDesc.join(';');
                    }
                    softphone.queue = queue;
                    softphone.simpleCommonCall("setagentqueue", queue);
                    $F.dialogClose(softphone.queueSelectDialog);
                }
            });
        });
    };

    /**
     * SCTIEvent简单处理并选择项目发出相关事件
     * 只有OnLogin和OnLogout是需要发给所有project，其他都是发送给当前电话的那个project
     */
    Softphone.prototype.notifySCTIEvents = function (type, sfInfo) {
        const softphone = this;
        if ($F.equalsIgnoreCase(type, "OnCallStart")) {
            softphone.getCallInfo(function (callInfo) {
                callInfo.setValue("callStartTime", $F.getDbTime());
                //根据menu中字段判断是否是当前项目的电话
                if ($E.staff.projects.length > 1) {
                    var callType = callInfo.getValue("callType");
                    if (callType == CallType.INBOUND) {
                        $.each($E.projects, function (i, proj) {
                            var dnis = callInfo.getValue("DNIS");
                            if (proj.isMatchProject(dnis)) {
                                $F.log("Project.CallStartHandler", "Select project tab to current project:" + proj.id);
                                softphone.currentProject = proj;
                                proj.events.notify($CONST.CTIEvent.CTI_ONCALLSTART, callInfo);
                                return false;
                            } else {
                                $F.log("Project.CallStartHandler", "No menu matched in this project: " + proj.id);
                            }
                        });
                    } else {
                        softphone.getCurrentProject().events.notify($CONST.CTIEvent.CTI_ONCALLSTART, callInfo);
                    }
                } else {
                    softphone.getCurrentProject().events.notify($CONST.CTIEvent.CTI_ONCALLSTART, callInfo);
                }
                $E.events.notify($CONST.CTIEvent.CTI_ONCALLSTART, callInfo);
            });
        } else if ($F.equalsIgnoreCase(type, "OnCallEstablish")) {
            softphone.getCurrentProject().events.notify($CONST.CTIEvent.CTI_ONCALLESTABLISH);
            $E.events.notify($CONST.CTIEvent.CTI_ONCALLESTABLISH);
        } else if ($F.equalsIgnoreCase(type, "OnCallEnd")) {
            softphone.getCurrentProject().events.notify($CONST.CTIEvent.CTI_ONCALLEND);
            $E.events.notify($CONST.CTIEvent.CTI_ONCALLEND);
        } else if ($F.equalsIgnoreCase(type, "OnLogin")) {
            $.each($E.projects, function (i, proj) {
                proj.events.notify($CONST.CTIEvent.CTI_ONLOGIN, sfInfo);
            });
        } else if ($F.equalsIgnoreCase(type, "OnLogout")) {
            $.each($E.projects, function (i, proj) {
                proj.events.notify($CONST.CTIEvent.CTI_ONLOGOUT);
            });
        } else if ($F.equalsIgnoreCase(type, "CallStateChange")) {
            softphone.getCurrentProject().events.notify($CONST.CTIEvent.CTI_CALLSTATECHANGE);
        } else if ($F.equalsIgnoreCase(type, "AgentStateChange")) {
            softphone.getCurrentProject().events.notify($CONST.CTIEvent.CTI_AGENTSTATECHANGE);
        } else if (type.toLowerCase().startWith("OnCallAction".toLocaleLowerCase())) {
            var arr = type.split(",");
            var actionType = arr[1];
            var dest = arr[2];
            softphone.getCurrentProject().events.notify($CONST.CTIEvent.CTI_ONCALLACTION, {
                type: type,
                actionType: actionType,
                dest: dest
            });
        }
    };

    /**
     * 软电话本身处理SCTI事件
     * @param type
     */
    Softphone.prototype.handleSCTIEvents = function (type) {
        var softphone = this, project = softphone.getCurrentProject();
        try {
            if (type === "callstatechange" || type === "agentstatechange") {
                if (type === "callstatechange") {
                    softphone.getCallInfo(function (callInfo) {
                        softphone.currentCallInfo = callInfo;
                        softphone.currentCallState = $F.parseInt(callInfo.getValue("callState2"));
                        softphone.currentAgentState = $F.parseInt(callInfo.getValue("agentstate"));
                        softphone.currentAgentMode = $F.parseInt(callInfo.getValue("agentmode"));
                        $F.log("Softphone.callstatechange", "Start to handle callState " + softphone.currentCallState + " agentState " + softphone.currentAgentState + " agentMode " + softphone.currentAgentMode);
                        if (softphone.currentCallState === CallState.ECT_TALKING) {
                            if (!softphone.callTimeTimer.running) {
                                softphone.baseStartTime = new Date().getTime();
                                softphone.callTimeTimer.start();
                            }
                            if (softphone.agentConferenced) {
                                softphone.agentConferenced = false;
                            }
                            if (softphone.agentTransfered) {
                                softphone.agentTransfered = false;
                            }
                        } else if (softphone.currentCallState === CallState.ECT_UNKNOWN) {
                            try {
                                softphone.callTimeTimer.stop();
                                softphone.agentConferenced = false;
                                softphone.agentTransfered = false;
                                if (!softphone.notClearNumberWhenECTUNKNOW) {
                                    $(BUTTONS.ANI).val('');
                                }
                            } catch (e) {
                                $F.err("Softphone - callstatechange", "Handle callState.ECT_UNKNOWN error:" + e);
                            }
                        } else if (softphone.currentCallState === CallState.ECT_HOLD) {

                        } else if (softphone.currentCallState === CallState.ECT_TALKINGHOLD) {
                            if (softphone.startInitTransfer) {
                                softphone.agentTransfered = true;
                            } else if (softphone.startInitConference) {
                                softphone.agentConferenced = true;
                            }
                        }
                        if (softphone.currentCallState === CallState.ECT_RINGING ||
                            softphone.currentCallState === CallState.ECT_DIALING ||
                            softphone.currentCallState === CallState.ECT_DIALINGHOLD) {
                            let callType = callInfo.getValue("callType"),
                                key = callType == CallType.INBOUND ? 'ANI' : 'DNIS',
                                number = callInfo.getValue(key);
                            if (!$F.isNull(number)) {
                                var masker = project.getCacheValue($CONST.CacheName.DB_MASKER, 'EVENT.' + key);
                                if (masker && masker.FORMAT) {
                                    softphone.currentCallNumber = CtlUtils.expression(number, masker.FORMAT);
                                } else {
                                    softphone.currentCallNumber = $F.shieldNumber(number,
                                        project.getParam("TELWLD"), project.getParam("TELSHD"), project.getParam("TELWLF"), project.getParam("TELSHR"));
                                }
                                $F.log("Softphone.callstatechange", "Set currentCallNumber by " + key + ":" + softphone.currentCallNumber);
                            }
                            $("#c_softphone .calltime").html("<span>00:01</span>");
                            if (!softphone.hideCallNumber) {
                                $("#c_softphone .sp_callnum").html("<span>" + softphone.currentCallNumber + "</span>");
                                softphone.callNumBlinkTimer.start();
                            }
                        } else {
                            if (!softphone.hideCallNumber) {
                                softphone.callNumBlinkTimer.stop();
                                $("#c_softphone .sp_callnum").html("<span>" + softphone.currentCallNumber + "</span>");
                            }
                        }
                        if (softphone.currentCallState === CallState.ECT_RINGING) {
                            softphone.answerBtnBlinkTimer.start();
                        } else {
                            softphone.answerBtnBlinkTimer.stop();
                        }
                        softphone.setAgentStateText();
                        softphone.setBtnStatus();
                        $F.log("Softphone.callstatechange", "Handle callState " + softphone.currentCallState + " done.");
                    });
                } else if (type === "agentstatechange") {
                    softphone.getAgentStateAndMode(function (agentInfo) {
                        softphone.currentAgentState = $F.parseInt(agentInfo.agentState);
                        softphone.currentAgentMode = $F.parseInt(agentInfo.agentMode);
                        $F.log("Softphone.agentstatechange", "Start to handle agentState " + softphone.currentAgentState + " and agentMode " + softphone.currentAgentMode);
                        if (softphone.currentAgentState !== AgentState.EAS_LOGOUT) {
                            softphone.setAgentLogined(true);
                            var showExtension = softphone.extension;
                            if ($F.parseInt(project.getParam("EXTSHD")) === 1) {
                                var extensionSheld = "";
                                for (var i = 0; i < softphone.extension.length; i++) {
                                    extensionSheld += "*";
                                }
                                showExtension = extensionSheld;
                            }
                            $("#c_softphone .extension").html(showExtension);
                            $("#c_softphone .agent_id").html(softphone.agentId);
                            if (softphone.queue) {
                                $("#c_softphone .sp_queue").show();
                                $("#c_softphone .sp_queue_id").attr('title', softphone.queueDesc || softphone.queue)
                                    .html(softphone.queueDesc || softphone.queue);
                            }
                        } else {
                            softphone.setAgentLogined(false);
                            $("#c_softphone .extension").text("");
                            $("#c_softphone .agent_id").text("");
                            $("#c_softphone .sp_queue").hide();
                        }
                        softphone.setAgentStateText();
                        softphone.setBtnStatus();

                        // 小修超时计时器
                        if (softphone.auxTimeout) {
                            if (softphone.currentAgentMode === AgentMode.EAM_AUX) {
                                if (!softphone.auxTimer) { // 避免重复收到事件造成启动重复定时器
                                    var checkAuxTimer = function (time) {
                                        softphone.auxTimer = setTimeout(function () {
                                            time--;
                                            if (time <= 0) {
                                                project.events.notify(EVENTS.AUX_TIMEOUT_EVT, {});
                                                softphone.auxTimer = null;
                                            } else {
                                                checkAuxTimer(time);
                                            }
                                        }, 1000);
                                    };
                                    checkAuxTimer(softphone.auxTimeout);
                                }
                            } else {
                                if (softphone.auxTimer) {
                                    clearTimeout(softphone.auxTimer);
                                    softphone.auxTimer = null;
                                }
                            }
                        }
                        $F.log("Softphone.agentstatechange", "Handle agentState " + softphone.currentAgentState + " and agentMode " + softphone.currentAgentMode + " done.");
                    });
                }
            } else if (type === "OnCallStart") {
                softphone.callTimeTimer.start();
                softphone.baseStartTime = new Date().getTime();
                if (project.getParam('SPBTIM') === '1') {
                    $('.sp_calltime .sp_block').html($F.lang('softphoneEle.sp_ringDuration'));
                }
                softphone.mediaType = softphone.attachData('mediaType');
            } else if (type === "OnCallEstablish") {
                if (project.getParam('SPBTIM') === '1') {
                    softphone.baseStartTime = new Date().getTime();
                    $('.sp_calltime .sp_block').html($F.lang('softphoneEle.sp_callDuration'));
                }
            } else if (type.startWith("OnCallAction")) {
                var arr = type.split(",");
                var actionType = arr[1];
                var dest = arr[2];
                if (actionType === "MakeCall" || actionType === "InitTransfer" || actionType === "InitConference" ||
                    actionType === "MuteTransfer" || actionType === "SingleStepTransfer" || actionType === "PhoneNo") {
                    softphone.startInitTransfer = false;
                    softphone.startInitConference = false;
                    if (actionType === "InitTransfer") {
                        softphone.startInitTransfer = true;
                    } else if (actionType === "InitConference") {
                        softphone.startInitConference = true;
                    }
                    if (actionType === 'PhoneNo') {
                        $(BUTTONS.ANI).val(dest);
                    }
                }
            } else if (type === "OnCallEnd") {
                softphone.getCallStat(function (callStat) {
                    softphone.refreshCallStat(callStat);
                });
                //电话结束时候，清空静音状态
                if (softphone.isMute) {
                    softphone.isMute = false;
                    hideBtn($(BUTTONS.UNMUTE));
                    showBtn($(BUTTONS.MUTE))
                }
            } else if (type == "73") {//notready
                softphone.getEvtDetail(function (data) {
                    $F.log("Softphone.handleSCTIEvents", "Evt detail: " + data.EvtDetail);
                    if (!$F.isNull(data.EvtDetail)) {
                        var details = data.EvtDetail.split("\|");
                        if ($.isArray(details) && details.length > 0) {
                            details.forEach(function (detail) {
                                if (detail.toLowerCase().indexOf("reasoncode") > -1) {
                                    var reasonCode = detail.substr(detail.indexOf("=") + 1);
                                    softphone.currentReasonCode = reasonCode;
                                    var auxDesc = softphone.auxMap[reasonCode];
                                    $F.log("Softphone.handleSCTIEvents", "Find aux : " + auxDesc + " with reason code " + reasonCode);
                                    softphone.setBreakTypeLabelText($F.parseEmpty(auxDesc));
                                }
                            });
                        }
                    }
                });
                // 如果开启保存auxdetail的话，notready事件中要去存这个表
                if (softphone.saveAuxDetail) {
                    if (softphone.auxDetail.guid && !softphone.auxDetail.saved) {
                        softphone.auxDetail.saved = true;
                        project.commonUpdateSync('Softphone.auxdetail.insert', [softphone.auxDetail.guid, $E.staff.id, project.groupId, softphone.agentId, softphone.extension, softphone.auxDetail.comments || '', softphone.auxDetail.id || '']);
                    }
                }
            } else if (type == "74") {//EVT_DATAUPDATED
                softphone.getEvtDetail(function (data) {
                    $F.log("Softphone.EVT_DATAUPDATED", "SCTIEventHandler 74 event detail: " + data.EvtDetail);
                    var parsedEvent = parseEventDetail(data.EvtDetail);
                    var evtObj = parsedEvent.evtObj;
                    var attachObj = parsedEvent.attachObj;
                    if (evtObj.hasOwnProperty("event")) {
                        if (evtObj["event"] == "74") {
                            softphone.getCallInfo(function (callInfo) {
                                let callType = callInfo.getValue("callType");
                                if (callType == CallType.INBOUND) {
                                    var newANI = attachObj["ani"];
                                    if (!$F.isEmpty(newANI)) {
                                        if (!softphone.hideCallNumber) {
                                            $("#c_softphone .sp_callnum").html("<span>" + newANI + "</span>");
                                        }
                                    }
                                }
                            });
                        }
                    }
                });
            } else if (type == "23") {//mute
                softphone.isMute = true;
                hideBtn($(BUTTONS.MUTE));
                showBtn($(BUTTONS.UNMUTE))
            } else if (type == "24") {//unmute
                softphone.isMute = false;
                hideBtn($(BUTTONS.UNMUTE));
                showBtn($(BUTTONS.MUTE))
            } else if (type == '1001') {
                softphone.updateAgentStateText($F.lang('softphone.extensionRinging'));
            } else if (type == '1002') {
                softphone.updateAgentStateText($F.lang('softphone.extensionEstablished'));
            } else if (type == '1003') {
                softphone.updateAgentStateText($F.lang('softphone.agentIdAnnouncing'));
            } else if ($F.equalsIgnoreCase(type, "OnLogout")) {
                softphone.currentCTIStatus = CTIStatus.LOGIN;
                //登录之后才去获取这个TransferOnDialingHold，因为可能根据不同坐席有不同结果
                softphone.getTransferOnDialingHold(function (data) {
                    softphone.transferOnDialingHold = data.TransferOnDialingHold;
                });
                //收到登录事件后，再次获取分机号，因为分机可能不是登录时候传递过去的分机
                softphone.getExtension(function (ret) {
                    $F.log('Softphone - OnLogin', 'Fetch current extension: ' + ret.extension);
                    softphone.extension = ret.extension;
                });
            } else if ($F.equalsIgnoreCase(type, "OnLogout")) {
                softphone.currentCTIStatus = CTIStatus.LOGOUT;
                softphone.currentAgentState = AgentState.EAS_LOGOUT;

                softphone.setAgentLogined(false);
                $("#c_softphone .extension").text("");
                $("#c_softphone .agent_id").text("");
                $("#c_softphone .sp_queue").hide();

                softphone.setAgentStateText();
                softphone.setBtnStatus();
            }

        } catch (e) {
            $F.err("Softphone - handleSCTIEvents", e.message);
        }
    };

    /**
     * 发出CTIEvent相关通知给框架
     * @param event
     */
    Softphone.prototype.handleCTIEvents = function (event) {
        const evt = parseEventDetail(event);
        const evtObj = evt.evtObj;
        // const attachObj = evt.attachObj;
        if (evtObj["event"] == "74") {//EVT_DATAUPDATED
            $F.log('Softphone - handleCTIEvents', 'EVT_DATAUPDATED with attachdata ', evt);
            for (let proj in $E.projects) {
                $E.projects[proj].events.notify($CONST.CTIEvent.EVT_DATAUPDATED, evt);
            }
        } else if (evtObj["event"] == "8") {//partyadded
            $F.log('Softphone - handleCTIEvents', 'CTI_PARTYADDED ', evt);
            for (let proj in $E.projects) {
                $E.projects[proj].events.notify($CONST.CTIEvent.CTI_PARTYADDED, evt);
            }
        } else if (evtObj["event"] == "9") {//partydeleted
            $F.log('Softphone - handleCTIEvents', 'CTI_PARTYDELETED ', evt);
            for (let proj in $E.projects) {
                $E.projects[proj].events.notify($CONST.CTIEvent.CTI_PARTYDELETED, evt);
            }
        } else if (evtObj["event"] == "22") {//partychanged
            $F.log('Softphone - handleCTIEvents', 'CTI_PARTYCHANGED with attachdata ', evt);
            for (let proj in $E.projects) {
                $E.projects[proj].events.notify($CONST.CTIEvent.CTI_PARTYCHANGED, evt);
            }
        } else if (evtObj["event"] == "11") {//evt_error
            $F.log('Softphone - handleCTIEvents', 'EVT_ERROR with attachdata ', evt);
            for (let proj in $E.projects) {
                $E.projects[proj].events.notify($CONST.CTIEvent.EVT_ERROR, evt);
            }
        } else if (evtObj["event"] == "100") {//EVT_MONITOR
            $F.log('Softphone - handleCTIEvents', 'EVT_MONITOR with attachdata ', evt);
            for (let proj in $E.projects) {
                $E.projects[proj].events.notify($CONST.CTIEvent.EVT_MONITOR, evt);
            }
        } else if (evtObj["event"] == "1077") {//EVT_RECORD_START (已经insert过RECORD)
            $F.log('Softphone - handleCTIEvents', 'EVT_RECORD_START with attachdata ', evt);
            for (let proj in $E.projects) {
                $E.projects[proj].events.notify($CONST.CTIEvent.EVT_RECORD_START, evt);
            }
        } else if (evtObj["event"] == "1078") {//EVT_RECORD_END
            $F.log('Softphone - handleCTIEvents', 'EVT_RECORD_END with attachdata ', evt);
            for (let proj in $E.projects) {
                $E.projects[proj].events.notify($CONST.CTIEvent.EVT_RECORD_END, evt);
            }
        }
    };

    /**
     * 给小修原因Label赋值
     * @param breakType
     */
    Softphone.prototype.setBreakTypeLabelText = function (breakType) {
        const breakTypeLabelDom = $("#c_softphone .sp_breaktype .sp_breaktype_label");
        if (!breakType) {
            breakTypeLabelDom.html("");
            $(BUTTONS.BREAK_TYPE_SELECT).val(0);
            this.currentReasonCode = "";
        } else {
            var originalBreakType = breakTypeLabelDom.html();
            if (originalBreakType !== breakType) {
                breakTypeLabelDom.html(breakType);
                $(BUTTONS.BREAK_TYPE_SELECT).find("option").each(function (i, o) {
                    if ($(o).text() === breakType) {
                        $(BUTTONS.BREAK_TYPE_SELECT).val($(o).val());
                    }
                });
                this.stateChange();
            }
        }
    };

    Softphone.prototype.checkCouldReady = function () {
        var project = this.getCurrentProject();
        if ($F.parseInt(project.getParam('CHAECS')) === 1) {
            var chatInstance = project.getModuleInstance($CONST.ModuleName.CHAT);
            if (chatInstance && chatInstance.logined && chatInstance.currentUserStatus == 1) { //登录chat 并且当前状态为在线
                return false;
            }
        }
        return true;
    };

    Softphone.prototype.breakCountDown = function (duration) {
        if (isNaN(duration)) return;
        if (BUTTONSTATE.BREAK.countingDown) {
            this.breakCountDown(duration);
        }
        var btn = $(BUTTONS.BREAK);
        BUTTONSTATE.BREAK.countingDown = true;
        $(BUTTONS.BREAK_TYPE_SELECT).attr('disabled', true);
        let colors = ['#f3f3f3', '#ff5f1d'];
        btn.css({background: 'none'});
        const task = function (duration) {
            btn.html(duration);
            btn.css({color: colors[duration % 2]});
            BUTTONSTATE.BREAK.timer = setTimeout(function () {
                if (duration > 0) {
                    duration--;
                    task(duration);
                } else {
                    BUTTONSTATE.BREAK.countingDown = false;
                    btn.html('').css({background: '', color: ''});
                    $(BUTTONS.BREAK_TYPE_SELECT).attr('disabled', false);
                }
            }, 1000);
        };
        task(duration);
    };

    Softphone.prototype.stopBreakCountDown = function () {
        if (BUTTONSTATE.BREAK.timer) {
            clearTimeout(BUTTONSTATE.BREAK.timer);
        }
        BUTTONSTATE.BREAK.countingDown = false;
        $(BUTTONS.BREAK).html('').css({background: '', color: ''});
        $(BUTTONS.BREAK_TYPE_SELECT).attr('disabled', false);
    };

    Softphone.prototype.setAuxDetail = function (id, comments) {
        if (this.auxDetail.id === id) {
            $F.log('Softphone - setAuxDetail', 'Duplicate aux id: ' + id);
            return;
        }
        const project = this.getCurrentProject();
        if (this.saveAuxDetail) {
            if (this.currentAgentState === AgentState.EAS_NOTREADY) { // 本来就处于未准备好时候，不会触发agentStateChange
                if (this.auxDetail.guid && this.auxDetail.saved) {
                    project.commonUpdateSync('Softphone.auxdetail.update', [this.auxDetail.guid]);
                    this.auxDetail = {};
                }
            }
        }
        this.auxDetail.guid = Guid.raw();
        this.auxDetail.id = id;
        this.auxDetail.comments = comments;
        if (this.saveAuxDetail) {
            if (this.currentAgentState === AgentState.EAS_NOTREADY) { // 本来就处于未准备好时候，不会触发agentStateChange
                this.auxDetail.saved = true;
                project.commonUpdateSync('Softphone.auxdetail.insert', [this.auxDetail.guid, $E.staff.id, project.groupId, this.agentId, this.extension, this.auxDetail.comments || '', this.auxDetail.id || '']);
            }
        }
    };

    Softphone.prototype.originalMakeCall = Softphone.prototype.makeCall;
    Softphone.prototype.makeCall = function (number, sData, callback) {
        const project = this.getCurrentProject(), params = {
            number
        };
        // 外拨之前发出事件，可以通过相应事件，并对事件参数赋值cancel为1，表示取消拨打
        project.events.notify($CONST.SoftphoneEvent.MAKE_CALL, params);
        if (params && params.cancel !== 1) {
            this.originalMakeCall(number, sData, callback);
        } else {
            callback();
        }
        $('.sp_call .sp_block').html($F.lang('softphoneEle.sp_outcallNumber'));
    };

    Softphone.prototype.originalReleaseCall = Softphone.prototype.releaseCall;
    Softphone.prototype.releaseCall = function (callback) {
        const project = this.getCurrentProject(), params = {};
        // 挂断之前发出事件，可以通过相应事件，并对事件参数赋值cancel为1，表示取消挂断
        project.events.notify($CONST.SoftphoneEvent.RELEASE_CALL, params);
        if (params && params.cancel !== 1) {
            this.originalReleaseCall(callback);
            softphone.setBtnStatus();
        } else {
            callback();
        }
    };

    Softphone.prototype.fireTransferToIVR = function (callback) {
        const project = this.getCurrentProject(), params = {};
        project.events.notify($CONST.SoftphoneEvent.TRANSFER_TO_IVR, params);
    };

    Softphone.prototype.fireTransferToQueue = function (callback) {
        const project = this.getCurrentProject(), params = {};
        project.events.notify($CONST.SoftphoneEvent.TRANSFER_TO_QUEUE, params);
    };

    Softphone.prototype.originalInitConference = Softphone.prototype.initConference;
    Softphone.prototype.initConference = function (number, sData, callback) {
        const softphone = this;
        softphone.originalInitConference(number, sData, function (d) {
            if (d) {
                $F.log("Softphone.InitConference", "InitConference success.");
                softphone.agentTransfered = false;
                softphone.agentConferenced = true;
            } else {
                $F.log("Softphone.InitConference", "InitConference fail.");
            }
            callback && callback(d);
        });
    };

    Softphone.prototype.originalCompleteConference = Softphone.prototype.completeConference;
    Softphone.prototype.completeConference = function (callback) {
        const softphone = this;
        softphone.originalCompleteConference(function (d) {
            if (d) {
                $F.log("Softphone.CompleteConference", "CompleteConference success.");
                softphone.agentConferenced = false;
            } else {
                $F.log("Softphone.CompleteConference", "CompleteConference fail.");
            }
            callback && callback(d);
        });
    };

    Softphone.prototype.originalInitTransfer = Softphone.prototype.initTransfer;
    Softphone.prototype.initTransfer = function (number, sData, callback) {
        const softphone = this;
        softphone.originalInitTransfer(number, sData, function (d) {
            if (d) {
                $F.log("Softphone.InitTransfer", "InitTransfer success.");
                softphone.agentTransfered = true;
                softphone.agentConferenced = false;
            } else {
                $F.log("Softphone.InitTransfer", "InitTransfer fail.");
            }
            callback && callback(d);
        });
    };

    Softphone.prototype.originalCompleteTransfer = Softphone.prototype.completeTransfer;
    Softphone.prototype.completeTransfer = function (callback) {
        const softphone = this;
        softphone.originalCompleteTransfer(function (d) {
            if (d) {
                $F.log("Softphone.CompleteTransfer", "CompleteTransfer success.");
                softphone.agentTransfered = false;
            } else {
                $F.log("Softphone.CompleteTransfer", "CompleteTransfer fail.");
            }
            callback && callback(d);
        });
    };

    Softphone.prototype.originalReconnect = Softphone.prototype.reconnect;
    Softphone.prototype.reconnect = function (callback) {
        const softphone = this;
        softphone.originalReconnect(function (d) {
            if (d) {
                $F.log("Softphone.Reconnect", "Reconnect success.");
                softphone.agentTransfered = false;
                softphone.agentConferenced = false;
            } else {
                $F.log("Softphone.Reconnect", "Reconnect fail.");
            }
            callback && callback(d);
        });
    };

    Softphone.prototype.startTokenCheck = function(options) {
        options = Object.assign({interval: 5000}, options);
        const proj = this.getCurrentProject();
        const doCheck = function(proj) {
            $F.dataService('JSGenerateServlet2', {
                data: {
                    token: proj.token,
                    dbPool : '',
                    name: 'Staff.token.check'
                },
                digest: proj.digest,
                success : function(data) {
                    if (data.code === -1) {
                        if (options.onFail) {
                            options.onFail()
                        }
                    } else {
                        setTimeout(function() {
                            doCheck(proj)
                        }, options.interval)
                    }
                }
            });
        };

        // 初始10秒后启动检查
        setTimeout(function() {
            doCheck(proj)
        }, 10000);
    };

    Softphone.prototype.isAgentReady = function() {
        return this.currentAgentState === AgentState.EAS_READY
    };

    Softphone.prototype.isCallBusy = function() {
        return this.currentCallState === CallState.ECT_DIALING || this.currentCallState === CallState.ECT_RINGING
            || this.currentCallState === CallState.ECT_TALKING || this.currentCallState === CallState.ECT_HOLD
            || this.currentCallState === CallState.ECT_DIALINGHOLD || this.currentCallState === CallState.ECT_TALKINGHOLD;
    };

    Softphone.prototype.isACW = function() {
        return this.currentAgentState === AgentState.EAS_NOTREADY && this.currentAgentMode === AgentMode.EAM_ACW
    };

    Softphone.prototype.reset = function() {
        this.agentLogined = false;
        this.currentCallState = CallState.ECT_UNKNOWN;
        this.currentAgentState = AgentState.EAS_LOGOUT;
        this.currentAgentMode = AgentMode.EAM_UNKNOWN;
        this.setAgentStateText();
        this.setBtnStatus();
        if (this.callTimeTimer) {
            this.callTimeTimer.stop()
        }
        if (this.callNumBlinkTimer) {
            this.callNumBlinkTimer.stop()
        }
        if (this.stateLastTimer) {
            this.stateLastTimer.stop()
        }
        if (this.answerBtnBlinkTimer) {
            this.answerBtnBlinkTimer.stop()
        }
        $F.log("Softphone - reset", "Reset state, callState " + this.currentCallState + " agentState " + this.currentAgentState + " and agentMode " + this.currentAgentMode);
    };

    ////////////////////////////////////////////////////////
    //          创建软电话对象 最终返回此对象             //
    ////////////////////////////////////////////////////////
    const softphone = new Softphone();

    const setBtnEnable = function (btn, enable) {
        if (enable) {
            btn.prop('disabled', false);
        } else {
            btn.prop('disabled', true);
            btn.mouseout();
        }
    };

    const showBtn = function (btn) {
        if (!btn || btn.length === 0) {
            return;
        }
        const display = btn.css('display');
        const dataShow = btn.attr('data-show');
        if (softphone.releaseCallVisible && btn.hasClass('.sp_hangup')) {
            btn.show();
            return;
        }
        if (softphone.muteVisible && btn.hasClass('sp_mute') && display === 'block') {
            btn.show();
            return;
        }
        if (softphone.nightRingVisible && btn.hasClass('sp_night_ring_on') && display === 'block') {
            btn.show();
            return;
        }
        if (softphone.holdVisible && btn.hasClass('sp_holding')) {
            btn.show();
            return;
        }
        if (softphone.initConferenceVisible && btn.hasClass('sp_init_conference')) {
            btn.show();
            return;
        }
        if (softphone.initTransferVisible && btn.hasClass('sp_init_transfer')) {
            btn.show();
            return;
        }
        if (softphone.initTransferIVRVisible && btn.hasClass('sp_transfer_to_ivr')) {
            btn.show();
            return;
        }
        if (softphone.initTransferQueueVisible && btn.hasClass('sp_transfer_to_queue')) {
            btn.show();
            return;
        }
        if (softphone.directTransferVisible && btn.hasClass('sp_direct_transfer')) {
            btn.show();
            return;
        }
        if (softphone.notReadyVisible && btn.hasClass('sp_not_ready')) {
            btn.show();
            return;
        }
        if (softphone.readyVisible && btn.hasClass('sp_ready')) {
            btn.show();
            return;
        }
        if (!dataShow) {
            btn.show();
        } else {
            hideBtn(btn);
        }
    };

    const hideBtn = function (btn) {
        btn.hide();
        btn.mouseout();
    };

    const checkBtnAvailable = function (buttonName) {
        if (!buttonName || !BUTTONSTATE[buttonName.toUpperCase()]) return true;
        if (BUTTONSTATE[buttonName.toUpperCase()].countingDown) {
            return false;
        }
        return true;
    };

    const parseEventDetail = function (event) {
        const ret = {
            evtObj: {},
            attachObj: {}
        };
        if (typeof event === 'object') {
            if ($E.debug)
                console.log('parseEventDetail: ' + JSON.stringify(event));
            $.each(event, function (k, v) {
                if (k === 'userdata' && v.type === 5) {
                    ret.attachObj = v.value;
                } else {
                    ret.evtObj[k] = v.value;
                }
            });
        } else {
            try {
                let eventBody = event.toString();
                let attachDatas = "";
                if (event.indexOf("#") > -1) {
                    eventBody = event.substring(0, event.indexOf("#"));
                    attachDatas = event.substring(event.indexOf("#") + 1);
                    if (!$F.isEmpty(attachDatas)) {
                        let attachDatasArr = attachDatas.split("|");
                        for (let i = 0; i < attachDatasArr.length; i++) {
                            let attachData = attachDatasArr[i];
                            if (attachData.indexOf("=") > -1) {
                                let attachDataKey = attachData.substring(0, attachData.indexOf("="));
                                let attachDataValue = attachData.substring(attachData.indexOf("=") + 1);
                                ret.attachObj[attachDataKey.toLowerCase()] = attachDataValue;
                            }
                        }
                    }
                }

                let evtArr = eventBody.split("|");
                for (let i = 0; i < evtArr.length; i++) {
                    let evt = evtArr[i];
                    if (evt.indexOf("=") > -1) {
                        let key = evt.substring(0, evt.indexOf("="));
                        ret.evtObj[key.toLowerCase()] = evt.substring(evt.indexOf("=") + 1);
                    }
                }
            } catch (e) {
                $F.err("Softphone - parseEventDetail", "Error occurred on parseEvent: " + e.message);
            }
        }

        return ret;
    };


    const BUTTONS = {
        ANSWER: "#c_softphone .sp_answer",
        RELEASE: "#c_softphone .sp_hangup",
        HOLD: "#c_softphone .sp_holding",
        RETRIEVE: "#c_softphone .sp_retrieve",
        MAKE_CALL: "#c_softphone .sp_dailing",
        INIT_CONFERENCE: "#c_softphone .sp_init_conference",
        COMPLETE_CONFERENCE: "#c_softphone .sp_complete_conference",
        INIT_TRANSFER: "#c_softphone .sp_init_transfer",
        COMPLETE_TRANSFER: "#c_softphone .sp_complete_transfer",
        RECONNECT: "#c_softphone .sp_reconnect",
        DIRECT_TRANSFER: "#c_softphone .sp_direct_transfer",
        NOT_READY: "#c_softphone .sp_not_ready",
        READY: "#c_softphone .sp_ready",
        BREAK: "#c_softphone .sp_break",
        BREAK_TYPE_SELECT: "#c_softphone .sp_breaktype .sp_breaktype_select",
        BREAK_TYPE: "#c_softphone .sp_breaktype",
        MUTE: "#c_softphone .sp_mute",
        UNMUTE: "#c_softphone .sp_unmute",
        NIGHT_RING_ON: "#c_softphone .sp_night_ring_on",
        NIGHT_RING_OFF: "#c_softphone .sp_night_ring_off",
        LOGIN: "#c_softphone .sp_signin",
        LOGOUT: "#c_softphone .sp_signout",
        NUM_CONTAINER: '#c_softphone .sp_num_container',
        ANI: '#c_softphone .sp_num_container .ani',
        ANI_HIS: '#c_softphone .sp_num_container .ani_his',
        NUM_KEYBOARD_SWITCHER: '#c_softphone .num_keyboard_switcher',
        NUM_KEYBOARD_CONTAINER: '#c_softphone .num_keyboard_container',
        NUM_KEYBOARD: '#c_softphone .num_keyboard_container .num_keyboard',
        VIDEO_ANSWER: "#c_softphone .sp_videoAnswer",
        VIDEO_RELEASE: "#c_softphone .sp_videoHangup",
        TRANSFER_TO_IVR: "#c_softphone .sp_transfer_to_ivr",
        TRANSFER_TO_QUEUE: "#c_softphone .sp_transfer_to_queue",
        EXPANDS: "#c_softphone .arrow"
    };

    const BUTTONSTATE = {
        ANSWER: {},
        RELEASE: {},
        HOLD: {},
        RETRIEVE: {},
        MAKE_CALL: {},
        INIT_CONFERENCE: {},
        COMPLETE_CONFERENCE: {},
        INIT_TRANSFER: {},
        COMPLETE_TRANSFER: {},
        RECONNECT: {},
        DIRECT_TRANSFER: {},
        NOT_READY: {},
        READY: {},
        BREAK: {},
        MUTE: {},
        UNMUTE: {},
        NIGHT_RING_ON: {},
        NIGHT_RING_OFF: {},
        LOGIN: {},
        LOGOUT: {},
        VIDEO_ANSWER: {},
        VIDEO_RELEASE: {},
        TRANSFER_TO_IVR: {},
        TRANSFER_TO_QUEUE: {},
        EXPANDS: {}
    };

    const IVR = function () {
        this.callback = undefined;
    };
    IVR.prototype = {
        /**
         * 转接到ivr
         * @param mute 是否是直接转
         * @param number 转接的号码
         * @param sData 随路数据
         * @param runtime 回调运行环境
         * @param cmdId 回调命令组id
         */
        transferToIVR: function (mute, number, sData, runtime, cmdId) {
            $F.log('IVR - transferToIVR', 'Call transferToIVR, mute: ' + mute + '  number: ' + number + ' sData: ' + sData);
            if (mute) {
                softphone.muteTransfer(number, sData);
            } else {
                softphone.initTransfer(number, sData);
            }
            if (runtime && cmdId) {
                $F.log('IVR - transferToIVR', 'Add call for runtime: ' + runtime.id + '  cmdId: ' + cmdId);
                this.callback = {
                    runtime: runtime,
                    cmdId: cmdId
                }
            }
        },

        /**
         * 转ivr成功，调用回调命令组
         * @param allAttachDatas 所有的随路数据
         */
        transferToIVRSuccess: function (allAttachDatas) {
            $F.log('IVR - transferToIVRSuccess', 'Call transferToIVRSuccess');
            if (this.callback) {
                this.callback.runtime.instance.doCmd(this.callback.cmdId, {
                    SDATA: allAttachDatas
                }, this.callback.runtime);
            }
            this.callback = undefined;
        },

        /**
         * 清空之前的回调命令组设置
         */
        interruptTransferIVR: function () {
            $F.log('IVR - interruptTransferIVR', 'Call interruptTransferIVR');
            this.callback = undefined;
        }
    };
    softphone.ivr = new IVR();


    return {
        getInstance: function () {
            return softphone;
        }
    };
});
